1

私はこの解決策をたくさん探しましたが、まったく運がありません。

これが私のプログラムの基本です。main関数にループがあります。ループは大量のデータを計算する必要があり、変数の1つに20より大きい値を指定すると、最終的にスタックオーバーフローが発生します。

関数で「return」を実行すると、スタック全体が解放されることを私は知っています。これが問題です。ユーザーがアプリを閉じるまで、このループを永久に実行する必要があります。

これも可能ですか?スタックオーバーフローが発生する前に、すべての関数で短い寿命が必要ですか?ダイナミックメモリを使用している場合でも、実行するたびに蓄積される他のスタックデータを取り除くことはできません。

基本的に、スタックオーバーフローが発生することなく、関数を永久に実行するにはどうすればよいですか?

4

2 に答える 2

3

スタックのサイズには制限があります。一部の Windows システムでは 1 MB です。プログラムでスタック サイズを変更できますが、多くの場合、それは悪い考えです。

各スレッドに異なるスタックがあります。スタック変数は、スコープの最後で常に解放されます。例えば

void MyFunction
{ // begin of scope 1
    std::string mouse("feep"); 
    for (int i = 0; i < 10000000; i++)
    { // begin of scope 2
        int x = 1;  // x is on the stack
        std::string cow("moo"); // cow is on stack
      // end of scope 2, cow is destroyed then the stack is freed for cow and x before the next iteration of the loop begins
    } 
    return; // end of scope 1, mouse is destroyed ant the stack is freed for mouse
}

上記のコードのスタックには、最大mouseで 、ix、およびが常に存在cowします。再帰を使用すると、オーバーフローする非常に深いスタックになる可能性があります。例えば

void StackOverflowIncoming()
{ // begin of scope
    int aVariableOnTheStack = 0;
    StackOverflowIncoming();
    // end of scope
}

上記の関数は、新しいスコープを永久に開き、スコープを離れることはないため、ある時点でオーバーフローします。

スタックをオーバーフローさせるもう 1 つの方法は、スタックallocaを直接割り当てる (スタックが割り当てられたスコープが閉じられるとすぐに解放される) です。alloca最大スタック サイズが 1 MB の場合、単純にスタックに 10 MB を割り当てるために使用します。スタックに巨大な構造体を割り当てることによっても実現できます。

void InstantStackOverflow()
{
    char buffer[1<<24];
}

スタックへの割り当てが多すぎるという詳細な例については、この質問を参照してください。

スタックをオーバーフローさせる最後の最も独創的な方法は、プログラムの状態を破壊することです。これにより、プログラムはひどく混乱し、スタックのクリーンアップに失敗します。通常、次のように、未定義の動作をもたらす言語機能を使用してこれを行います。

void TryToCorruptTheStack()
{ // begin of scope
    char buffer[1];
    for (int i = -20; i < 20; i++)
        buffer[i] = 5;
    // end of scope
}

スタック破損のより詳細な例については、この質問を参照してください。

于 2012-12-13T16:59:21.487 に答える
2

関数を実行してもスタックはいっぱいになりません。ただし、再帰関数呼び出しを使用している場合は、最終的にスタックがオーバーフローします。あなたの質問に戻って、スタックオーバーフローを引き起こすメイン関数でループを実行していると言い、関数を呼び出すとスタックオーバーフローが発生すると言います。ループ内で新しいオブジェクトを作成しない限り、ループによってスタック オーバーフローが発生することはありません。繰り返しますが、C/C++ では、メイン関数を再帰的に呼び出すことはできません。あなたは明確な友達ではありません。

サンプルコードを共有していただければ幸いです。

PS: 面白いです。stackoverflow の stackoverflow について話している:P

于 2012-12-13T16:59:19.017 に答える