スタック オーバーフロー エラーとは何ですか? どのタイプのプログラム/プログラミング言語で発生する可能性がありますか? Web アプリケーション コードで発生する可能性は低いですか?
7 に答える
ウィキペディアから:
ソフトウェアでは、コールスタックで使用されるメモリが多すぎると、スタックオーバーフローが発生します。多くのプログラミング言語では、コールスタックに含まれるメモリの量は限られており、通常はプログラムの開始時に決定されます。
スタックは、プログラムのサブルーチンが実行を終了したときに制御を返す必要があるポイントの記録を保持するデータ構造です。サブルーチンが呼び出されると、リターンアドレスがスタックにプッシュされ、サブルーチンが実行を終了すると、リターンアドレスがスタックからプルされます。多くのサブルーチンがあり、スタックにスペースがない場合、スタックオーバーフローが発生します。
また、スタックにはローカル変数を格納することを目的としているため、ローカル変数が大きすぎる場合は、スタックに格納するスペースがない可能性が高くなります。この場合、スタックオーバーフローも発生します。
DrawLine
ウィキペディアには、と呼ばれる別のサブルーチンからサブルーチンが呼び出されたときのスタックを示す優れた図が含まれていDrawSquare
ます。この図がスタック構造をよりよく理解するのに役立つことを願っています。
スタックオーバーフローの主な原因は2つあります。深い関数の再帰と過度に大きなスタック変数です。これらはほとんどすべてのプログラミング言語で一般的な用語であるため、言語の複雑さに加えてスタックオーバーフローが発生する可能性があります。
Guffaの貢献:スタックはガベージコレクションとは何の関係もありません。最近のアプリケーションはスタックが大きいため、スタックオーバーフローが発生する可能性はわずかに低くなりますが、それ以外は違いはありません。
スタックには多数のスタック フレームが含まれ、メモリに格納されます。関数が呼び出されるたびに、新しいスタック フレームがスタックに追加されます。スタック フレームには、呼び出された関数に渡される引数と戻りアドレスが含まれているため、呼び出された関数が終了すると、CPU はどこに戻るべきかを認識し、呼び出し関数の実行を続行できます。スタック フレームには、呼び出される関数のローカル変数によって使用されるメモリが含まれている場合もあります。
この例では、Main 関数は WriteCustomerDetails を呼び出し、PrintToConsole を呼び出して、WriteCustomerDetails 関数が検索したデータの個々のビットを書き出します。
'=======スタックの一番上====================='
Function: PrintToConsole
Arg: John Smith, 34 Acacia Avenue, Age 23
'-- -------------------------------------------------- -------'
Function: WriteCustomerDetails
Arg: John Smith
'---------------------------------- -------------------------'
Function: Main
'======スタックの一番下=========== ========'
スタックに十分なスペースが予約されていない場合、スタック オーバーフローが発生します。通常、スタックは 1 つの大きな連続したメモリ ブロックに配置されるため、チャンクに分割されません。これは、スタックに 1 つの大きなメモリが必要であることを意味し、ランタイムがスタック用に予約されたスペースを拡張しようとするのが難しくなります。埋まったら。
スタック オーバーフローは、自分自身を呼び出す関数が誤って記述された場合によく発生します。ある時点で呼び出しを停止する「if」または関数内の条件がある限り、関数がそれ自体を呼び出しても問題ない場合があります。これを再帰関数と呼びます。しかし、停止せずに関数が自分自身を呼び出し続けている場合、または 2 つ以上の関数が互いに呼び出し続けている場合は、スタック メモリをすべて使い果たしてしまいます。何も残っていない場合、スタック オーバーフローが発生し、プログラムがクラッシュします。
これはどのプログラムでも発生する可能性があり、必ずしも複雑である必要はなく、Web サイトを実行するコードで発生する可能性があります。また、スクリプト言語でも発生する可能性があります。
スタック スペースを使いすぎると、スタック オーバーフローが発生します。通常、これが発生する状況は 2 つあります。
1 つ目は、コードにエラーがあり、終了せずに再帰ループが発生した場合です。たとえば、それ自体から読み取るプロパティ:
public int Length {
get {
return Length;
}
}
2 つ目は、再帰ループが深すぎる場合です。スタック スペースが限られているため、アルゴリズムを特定の回数しかネストできません。アルゴリズムのネストが深すぎて、存在する前にスタック スペースが不足すると、スタック オーバーフローが発生します。例:
public bool Odd(int value) {
if (value == 0) {
return false;
} else {
return !Odd(value - 1);
}
}
大きすぎる値でこのメソッドを呼び出すと、ネストが深すぎてスタック オーバーフローが発生します。
ウィキペディアから、当然のことながら:
ソフトウェアでは、コールスタックで使用されるメモリが多すぎると、スタックオーバーフローが発生します。多くのプログラミング言語では、コールスタックに含まれるメモリの量は限られており、通常はプログラムの開始時に決定されます。コールスタックのサイズは、プログラミング言語、マシンアーキテクチャ、マルチスレッド、使用可能なメモリの量など、多くの要因によって異なります。コールスタックで使用されるメモリが多すぎると、スタックはオーバーフローすると言われます。通常、プログラムがクラッシュします。1このクラスのソフトウェアバグは通常、2種類のプログラミングエラーのいずれかによって引き起こされます。
スタックオーバーフローは、スタックを使用しているときに発生し(duh ...)、メモリの割り当て/読み取りに問題があります。「Webプログラム」では、(HTML、PHP、JSについて話していると思いますが)スタックを使用しないか、使用する言語で低レベルのメモリ制御ができないため、これらの問題を防ぐことができます。