3

アプリケーションで何が原因なのかさえわかりません。それは何ですか?クラスの新しいインスタンスを作成しました (クラスは別のファイルにありました) が、メソッドを初めて呼び出すと、StackOverFlow 例外がスローされます。

論理的にスタック オーバーフロー例外をスローすると私が考える唯一のことは、誰かが Jon Skeet に反対票を投じた場合です。

しかし、真剣に今、それは何ですか?最初のクラスと同じファイルに別のクラスを作成し、それを使用してメソッドを呼び出すことで、この問題を回避しました。

4

9 に答える 9

6

原則として、スタック オーバーフロー例外は、再帰の深さが (通常は) 固定スタック制限を超えた再帰アルゴリズムによって発生します。これは通常、アルゴリズムのバグの結果ですが、アルゴリズムを適用するデータ構造が「深すぎる」​​ことが原因である可能性もあります。

これは、バグのある再帰の簡単な例です (特定の PL ではありません)。

function int length(list l) {
    if (empty(l)) {
        return 0;
    } else {
        return 1 + length(l);  // should be 'return 1 + length(tail(l));
    }
}

空でないリストに対して length を呼び出すと、一般的なプログラミング言語でスタック オーバーフローが発生します。ただし、バグを修正したとしても、長いリストのメソッドを呼び出すと、スタック オーバーフローが発生する可能性があります。

(例外は、末尾再帰の最適化をサポートする言語 ... またはより厳密にはコンパイラ ... を使用する場合です。)

于 2009-09-20T03:16:14.943 に答える
4

スタック オーバーフロー例外は、割り当てられたスタック サイズを超えた場合に発生します。これは通常、メソッドを再帰的に呼び出して決して離れないことから発生します。また、さまざまなあいまいなメソッド チェーンが原因である可能性もあります。問題は、オブジェクトに次の程度の何かがある可能性があることです。

void MyMethod()
{
    MyMethod();
}

呼び出しは実行を終了せず、エントリ ポイントを維持する必要があるため、使用されているスタック スペースが消費され、解放されることはありません。

PS SO は、問題の特定の例外 (これは基本的なものであり、.NET に限定されるものではありません) にちなんで名付けられました。これは、開発者サイトの巧妙な名前です。

于 2009-09-20T03:17:48.233 に答える
2

StackOverFlows 例外はまさにそのように聞こえますが、スタック オーバーフローです。通常、これはメソッドに循環依存があるためです。たとえば、メソッド A が B を呼び出し、B が A を呼び出します。または、基本ケースのない再帰的メソッドである可能性があります。

于 2009-09-20T03:16:29.320 に答える
2

コードを見ないと、なぜこれが起こったのかを知ることはできませんがStackOverflowException、スレッドが呼び出しスタックをオーバーフローしたときに a がスローされます。これは、メソッドが条件付きブレークなしで再帰的に呼び出し、無限再帰を作成する場合に最もよく発生します。再帰ごとに新しいスタック フレームが作成されるため、無限再帰は理論的に無限の数のスタック フレームを作成します。「スタック オーバーフロー」という用語が適切である理由がわかるはずです。

于 2009-09-20T03:16:38.120 に答える
2

スタックは、コンピューターが現在呼び出されている関数のリストと、使用されている変数とパラメーターを格納する場所です。したがって、関数 Main が関数 A を呼び出し、次に関数 A が関数 B を呼び出し、それらが変数 c、d、および e を使用する場合、スタックにはそのすべての情報が含まれます。ただし、スタックは非常に大きいだけです。そのため、関数 B が関数 D を呼び出す関数 C を呼び出し、関数 D などを呼び出すと、最終的に何百ものネストされた関数が作成され、最終的にスタックが「オーバーフロー」します。別の関数呼び出しを格納するための十分なスペースがありません。

他の人が指摘しているように、これは通常、再帰関数で発生します (関数 B が関数 B を呼び出し、関数 B が関数 B を呼び出します...) - 最終的に、スタックがオーバーフローします。その再帰関数が呼び出されている場所と、再帰ループから抜け出せない理由を見つける必要があります。

もちろん、問題はバグのある再帰アルゴリズムであるということではありません。関数呼び出しの数がスタックのサイズを超えているだけかもしれません。したがって、アルゴリズムが再帰関数を数百回呼び出す可能性がある場合、それはそうかもしれません。

于 2009-09-20T03:25:25.860 に答える
1

これは通常、関数の再帰呼び出しが終了しない場合に発生します。これはいくつかの方法で取得できます。1 つの方法は、基本ケースのない再帰アルゴリズムである可能性があり、別の一般的な方法は、オブジェクト A と B を作成して、コンストラクターで互いの 1 つを作成するなどです。

デバッガーをステップ実行して調べることをお勧めします:)

于 2009-09-20T03:18:27.383 に答える
0

この問題が発生しましたが、lstEncounter の入力ミスに気付きました。C++ のクラスで学んだように、問題は基本的に同じパラメーターで自分自身を呼び出す再帰アルゴリズムです。エラーが発生した私の例:

Property Encounter(ByVal N As Integer)
    Get
        If N < lstEncounters.Count Then
            Return Encounter(N)
        Else
            Return Nothing
        End If
    End Get
    Set(value)
        lstEncounters(N) = value
    End Set
End Property
于 2014-12-25T05:44:45.493 に答える
0

私は最近、古い VB6 アプリケーションを VB.NET に移植しました。VB.NET は巨大な再帰関数を使用して大量のデータを並べ替えました。アルゴリズムは問題ありませんでしたが、実行すると一貫してスタック オーバーフロー エラーが発生しました。いじくり回した後、VB がコードの背後で多くの魔法を行っていることに気付きました。簡単な型キャストには代償が伴います。そのため、再帰関数は、型変数を使用する代わりに遅延バインディングに依存しすぎていたため、大量のキャスト、解析などのオーバーヘッドが発生しました (1 行のコードで 2 から 10 の関数を呼び出すことができます...)。明らかに、スタックをオーバーフローさせました。

TL;DR: DirectCast() と静的バインド (型付き変数) を使用して、VB が再帰関数で実行時にスタックをフラッディングするのを防ぎます。

于 2014-06-26T19:20:43.787 に答える