スタック領域を浪費した結果、オーバーフロー( Overflow /桁あふれ )が発生します。

関数で再帰処理を行う際に、「出口処理」を適切に行わなかった場合などに発生します。

サンプルコード

再帰を用いてスタックオーバーフローを実際に発生させてみましょう。

ユークリッドの互除法は最大公約数を求める手法の一つで、人類史上最古のアルゴリズムの一つとも言われますが、以下サンプルコードは関数に与える二つの引数の内どちらかに 0 およびマイナス値を与えてやればオーバーフローとなります。

GM:Studio 内でユーザ定義関数として以下コードを呼び出してください。

    EuclideanAlgorithm(252,-105);

とでもすればスタックオーバーフローです。

    EuclideanAlgorithm(252,105);

こうすれば最大公約数として 21が返ってきます。

///EuclideanAlgorithm(numberA , numberB);
//再帰を使って最大公約数を求める
//Greatest Common Divisor(GCD)
var a = argument0;
var b = argument1;

    if      (a == b){ return a;};
    //else if (a <= 0 || b <= 0) {return "Nothing";};
    
    if (a > b)
    {
    return EuclideanAlgorithm(a-b, b);
    }
    else
    {
    return EuclideanAlgorithm(a, b-a);
    };

上記コードは、再帰処理によって無限に値が増加するような引数を与えた場合、もしくは再帰を用いても次関数呼び出しで引数の値が変わらない場合に無限ループとなります。

このように再帰とは「出口処理」と呼ばれるループから脱出する処理が必須で、出口処理が適切でない場合にスタックオーバーフローを発生させます。

参考( wikipedia 英語版の方が充実してる):Euclidean_algorithm

出口を使って脱出する

Leave a Reply

Your email address will not be published. Required fields are marked *