2009-07-10 10 views
33

スタックオーバーフローエラーとは何ですか?どのような種類のプログラム/プログラミング言語が起こりそうですか? Webアプリケーションコードで発生する可能性は低いですか? wikipediaから、クーゼのスタックオーバーフローとは何ですか?

+0

http://en.wikipedia.org/wiki/Stack_overflow –

答えて

26

:あまりにも多くのメモリが コールスタック上で使用されている際に、ソフトウェアで

、スタックオーバーフローが を発生します。多くのプログラミング 言語では、呼び出しスタックには メモリが含まれています。通常、 は、 プログラムの開始時に決定されます。

スタックは、プログラムのサブルーチンが実行を終了した時点で制御を返すべきポイントを記録するデータ構造です。サブルーチンが呼び出されるときに戻りアドレスはがスタックにプッシュです。サブルーチンが実行を終了すると、戻りアドレスはがスタックから引き出されますです。多くのサブルーチンがあり、スタックにスペースがない場合は、スタックオーバーフローが発生します。

また、スタックにはローカル変数が格納されているので、ローカル変数が大きすぎるとスタックに格納するスペースがない可能性が高くなります。スタックオーバフローも起こります。

DrawLineサブルーチンがDrawSquareという別のサブルーチンから呼び出されたときに、Wikipediaにスタック図が表示されているので、この図がスタック構造の理解に役立つことを願っています。 深い関数再帰過大なスタック変数

stack diagram

は、スタックオーバーフローの二つの主な原因があります。これらはほとんどすべてのプログラミング言語で一般的な用語であるため、言語の複雑さに加えてスタックオーバーフローが発生する可能性があります。

Guffa投稿:スタックはガベージコレクションとは関係ありません。最近のアプリケーションではスタックが大きいので、スタックのオーバーフローが発生する可能性はわずかに低くなりますが、それ以外は違いはありません。

+1

私が理解していることから、これはガベージコレクションのある現代語では(少なくともあまりないほど、私はあまりよく分かりませんが)起こりません。 – thebrokencube

+1

もちろん、スクリプト言語で発生する可能性があります。彼らはコールスタックを持っており、それは自然にオーバーフローする可能性があります。 – Guffa

+1

ええ、それは非常に深い再帰を使用すると、Javaで発生する可能性がありますhttp://stackoverflow.com/questions/860550/stack-overflows-from-deep-recursion-in-java –

5

:あまりにも多くのメモリがコールスタック上で使用されている際に、ソフトウェアで

は、スタックオーバーフローが発生します。多くのプログラミング言語では、コールスタックには限られた量のメモリが含まれており、通常はプログラムの開始時に決定されます。コールスタックのサイズは、プログラミング言語、マシンアーキテクチャ、マルチスレッド、使用可能なメモリの量など、多くの要因によって異なります。呼び出しスタック上で使用されるメモリが多すぎると、スタックはオーバーフローしていると言われます。通常はプログラムがクラッシュします。 1このクラスのソフトウェアバグは、通常2種類のプログラミングエラーのいずれかによって発生します。

+1

+1ちょっとあなたががぶら下がったまま... – steamer25

+1

これは私が探している答えではありません –

+1

しかし、この回答は良いと思います。 –

1

ha英語は理解しにくいですが、私はあなたの求めるものを得ると思います。

スタックを使用しているとき(duh ...)、メモリの割り当て/読み取りの問題が発生すると、スタックオーバーフローが発生します。 (あなたがHTML、PHP、JSについて話していると仮定していると仮定して)スタックを使わないか、あるいは使用される言語がこれらの問題を防ぐ低レベルのメモリ制御を許さない。 Wikipediaから

+2

メモリ割り当ての制御が不足していても、スタックオーバーフローを防ぐことはできません。 –

+2

ちょうどおよそすべての言語にコールスタックがあります。サブルーチンが終了した後のコードに戻ることができるようにするには、呼び出しスタックが必要です。このコールスタックは通常固定サイズであるため、返さずに非常に多くのサブルーチンを呼び出した後、スタックはいっぱいになりオーバーフローします。 –

18

スタックにはいくつかのスタックフレームが含まれ、メモリに格納されます。 関数が呼び出されるたびに、新しいスタックフレームがスタックに追加されます。スタックフレームには、呼び出される関数に渡す引数と戻りアドレスが含まれているので、呼び出された関数が終了すると、どこに戻るかをCPUが知っているので、呼び出し関数を実行し続けることができます。スタックフレームは、呼び出される関数のローカル変数によって使用されるメモリも含むことができます。この例では

、WriteCustomerDetailsとPrintToConsoleがWriteCustomerDetails関数がルックアップするデータの個々のビットを書き込むために呼び出され、その呼び出されるメイン関数:

「=======スタックのトップ==== ================= '
機能:PrintToConsole
Arg:John Smith、34 Acacia Avenue、Age 23
' ----------- ------------------------------------------------ '
機能:WriteCustomerDetails
のArg:ジョン・スミス
'------------------------------------------------ -----------」
機能:メイン
'======スタックの最下部==================='

スタックの十分な領域が予約されていない場合、スタックのオーバーフローが発生します。通常、スタックは1つの大きな連続したメモリブロックに位置するため、チャンクに分割されません。つまり、大きなメモリが必要です。これにより、ランタイムがスタック用に予約された領域を試して成長させることが難しくなりますそれがいっぱいになると。機能が誤って自分自身を呼び出し、その書き込まれたとき

スタックオーバーフローが頻繁に発生することができます。場合によっては、ある点で呼び出しを停止する「if」や関数の条件が存在する限り、関数自体が呼び出しても問題ありません。これは再帰関数と呼ばれます。しかし、何も停止しておらず、関数が自分自身を呼び出し続けている場合、あるいは2つ以上の関数が互いに呼び出し続けている場合、非常に迅速にスタックメモリをすべて消費します。何も残っていないと、スタックオーバーフローが発生し、プログラムがクラッシュします。

すべてのプログラムで発生するため、彼らは必然的に複雑である必要はありませんし、それは、ウェブサイトを実行しているコードで発生することが可能です。また、スクリプト言語でも発生する可能性があります。

+1

非常に良い答え、+1 –

7

多すぎるスタック領域を使用すると、スタックのオーバーフローが発生します。あなたが終了せずに再帰ループを引き起こし、コードに誤りがある場合

最初は次のとおりです。一般的にこの問題が発生した二つの状況があります。たとえば、それ自身からプロパティを読み込む場合:

public int Length { 
    get { 
     return Length; 
    } 
} 

2番目は、再帰的ループが深すぎる場合です。スタックのスペースは限られているので、特定の回数だけアルゴリズムをネストすることができます。アルゴリズムのネストが深すぎて、スタック領域がなくなるまでスタック領域がなくなると、スタックオーバーフローが発生します。例:

public bool Odd(int value) { 
    if (value == 0) { 
     return false; 
    } else { 
     return !Odd(value - 1); 
    } 
} 

このメソッドを大きすぎる値で呼び出すと、ネストが深すぎてスタックオーバーフローが発生します。

+3

あなたの例の両方でスタックオーバーフローの理由は再帰です。しかし、本当に別の理由があります。スタックに割り当てられた(ローカルの)変数または関数の引数が大きすぎる場合、通常は配列で発生します。http://en.wikipedia.org/wiki/Stack_overflow –

関連する問題