2011-07-17 9 views
0

スタックオーバーフロー例外が何であるか正確にはわかりません。別の形でメソッドを呼び出すと、このエラーが出ます。スタックオーバーフロー例外を定義してください - C#

+2

いくつかのコードを投稿した方が良いでしょう。私たちが実際に行っていることを行うことができます。あなたの例外を修正するのに役立ちます。簡単に検索可能な用語を定義しません。 –

答えて

7

プログラムが誤動作することがあります。プログラマは、ロジックを実装し、それが正しく動作することをテストすることによって、プログラムを記述します。しかし、プログラマがロジックを間違えた場合、悪いことが起こる可能性があります。

おそらく、プログラムが失敗する可能性のある最も一般的な方法の1つは、無限ループです。

static int Sum(int n) 
{ 
    int sum = 0; 
    int i = 1; 
    while (i <= n) 
     sum += i; 
    return sum; 
} 

どうなります:最初ののn整数を追加しようとすると、このサンプルプログラムを取りますか?バグはどこですか? iをインクリメントするのを忘れてしまい、nを超えることはありません。これを実行すると実行され、ハングします。それは決してそれ自身で止まらないでしょう。

しかし、プログラム内に無限ループがあり、そのループにのリソースを使用すると、リソースが不足する可能性があります。再帰を使って和を求める別のプログラムを考えてみましょう:

static int RecursiveSum(int n) 
{ 
    return n + RecursiveSum(n - 1); 
} 

このメソッドもバグです。終了条件を含めるのを忘れてしまったので、「無限ループ」もあります。実行するとどうなりますか?

処理は、StackOverflowExceptionのために終了します。

C#では、メソッドを呼び出すたびにスタックと呼ばれるリソースを少し使います。スタックは、プログラムが誰が誰を呼び出したかを記録しておくことができるので、メソッドが返ってきたときに正しい場所に戻ります。メソッド引数とローカル変数もスタック領域を使います。メソッドが終了して戻るとき、それらは使用したスタックスペースを解放します。

スタックはメモリを使用しているため、時間のような無限のリソースではありません。

だから、プログラムが生成できる2つの主要な方法がありますStackOverflowException

  1. あまりにも多くの再帰呼び出しレベルの
  2. シリーズを返すことはありませんメソッドを呼び出すメソッドを呼び出す方法の無限ループというを希望最終的には終わりですが、最初にスタックがなくなってしまいます。

最初の問題は上記の2番目の方法で示されています。しかし、終了条件を追加するためにその方法を修正しても、小さな数値に対しては機能しますが、nという十分大きな値の合計を生成する前に、最終的には失敗します。

ほとんどの園芸品種StackOverflowExceptionは最初のタイプですが、再帰を慎重に使用しないと、2番目の問題にも対処できます。

StackOverflowExceptionをデバッグするときにコールスタックは、多くの場合、次のようになります。Cを呼び出してから、再度Aを呼び出し

... 
Program.RecursiveSum(int n = -7770) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7769) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7768) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7767) Line 26 + 0xf bytes C# 
Program.RecursiveSum(int n = -7766) Line 26 + 0xf bytes C# 
The maximum number of stack frames supported by Visual Studio has been exceeded.  

または時々A通話Bなどをあなただけのループを見つける必要があり、設定inのブレークポイントは、何が起こっているかを診断します。

+0

もちろん、C#にテールコールエミッションコンパイラがあれば、この例ではスタックオーバーフローが発生しないかもしれません; p –

+0

うわー...これは本当に助けになりました!ありがとう! –

6

stack overflowは、お互いを呼び出すメソッドが多すぎる場合に発生します。

あなたのコードが関数を呼び出すときはいつでも、ランタイムはその関数を呼び出したときにあなたがいたところの呼び出しスタック呼び出しスタックにエントリをプッシュします。関数が終了すると、ランタイムはスタックのntryをポップしてそこに戻ります。

このスタックがいっぱいになると、スタックのオーバーフローが発生します。

1

スタックオーバーフローは、スタック領域を使い果たしたときです。スタック領域は、通常、メソッド呼び出しによって消費されます。メソッド呼び出しでは、引数値がスタックにプッシュされます(メソッドがスタックからポップ/削除されたときに戻ります)。スタックオーバーフローが発生する最も一般的なケースは、何らかの再帰(自身を呼び出すメソッド)がある場合です。各メソッド呼び出しでは、スタックオーバーフローが発生したときまで、もう少しスタックスペースを消費します。

関連する問題