2011-02-03 14 views
1

深い再帰を使用するアルゴリズムがあります。再帰がどれだけ深いレベルになるかは、入力によって異なります。スタックオーバーフローの例外を避けるために、私は深さのカウントを保持し、特定の深さで終了します。.NETでスタックオーバーフロー例外が発生する要因は何ですか?

私はこれまで、少しレベルを上げて、500点を止めることを決めました。しかし、突然、突然300を超えるレベルでスタックオーバーフローの例外が発生します。

これに影響を与える要因は誰か分かりませんか?それは? CPUとRAM?または、他のどのプロセスがコンピュータ上で実行されているかと関連していますか?

+0

任意の時点で「安全に」終了できるのであれば、なぜそれほど深く進む必要がありますか? –

+0

これはあなたの質問に直接答えるものではありませんが、F#(C#/ VBとは異なります)はテールコール再帰をサポートしているため、スタックオーバーフローの例外を受けずに正しく書かれた再帰アルゴリズムを無限に繰り返すことができます。あなたのアルゴリズムをF#で書いて、今使っている言語から呼び出すことは価値があるかもしれません。 –

+2

@Joel:Nitpick:F#は、テールコール再帰呼び出しを効果的に繰り返しステートメント(ループ)に変換して最適化します。NET言語はテールコール再帰をサポートしていますが、自動的には変換しません。詳細については、この回答を参照してください:http://stackoverflow.com/questions/310974/what-is-tail-call-optimization/310980#310980 –

答えて

1

答えは異なり、ここを参照してください:あなたが再帰的でないためにあなたのアルゴリズムを変更することが賢明だろうStack capacity in C#

、あなたが再帰ことができますどのくらい見て容易ではないだろう、とあなたならば、基本的に、あなたは運命を誘惑しています証明のレベルの再帰深度を予測しようとします。それと、スタック深度に使用する推定アルゴリズムは、次の.NETサービスパックで壊れる可能性があります。

3

スタック領域が不足するとStackOverflowExceptionになります。メソッドを呼び出すと、その関数で使用されるローカル変数と同様に、スタック・スペースと呼ばれるスタック・スペースが使用されます。再帰は、古いスタックフレームをポップすることなく、新しいスタックフレームを継続的に追加します(テールコール最適化を採用していない限り、C#はそれほどうまく機能しません)。

したがって、正確にこれが発生するのは、メソッド呼び出しの数だけでなく、これらのメソッド内で何をしているのかによっても異なります。

+0

ありがとうございます。私は、私の質問を少し違ったものにしていると思います。スタックのスペースはどれくらいありますか、どんな要因がどれだけ影響を与えることができますか? – Rask

2

この説明は、Java、C、C++言語のStackOverflowExceptionの背後にある基本的な理由です。

Stackoverflow例外は、再帰的なメソッド呼び出しのためにどの言語でも一般的に発生します。

無限回帰ループのためにそれ自身または他の方法を呼び出すメソッドがあるとしたら、StacoverflowExceptionが発生します。この背後にある理由は、メソッド呼び出しスタックがいっぱいになり、他のメソッド呼び出しを受け入れることができなくなるためです。

メソッドコールスタックは次の図のようになります。

enter image description here

説明 - 主な方法は、5つの文と第三の方法があるとしmethodAへの呼び出しがあり、その後、mainメソッドの実行がstatement3で一時停止されますとMethosAは、コールスタックにロードされます。次にメソッドAはメソッドBを呼び出します。メソッドBもスタックにロードされます。

このように、無限の再帰呼び出しによって、呼び出しスタックがいっぱいになります。だから、これ以上の方法はありません。したがって、StackOverflowExceptionがスローされます。

関連する問題