11

私はスレッドの1つを通過していました。関数内でローカルに 10^6 の配列を宣言したため、プログラムがクラッシュしました。

与えられた理由は、スタックでのメモリ割り当ての失敗がクラッシュにつながるためです。

同じ配列がグローバルに宣言された場合、うまく機能しました(ヒープ上のメモリが保存されました)。

ここで、スタックが下向きに成長し、上向きにヒープするとします。

我々は持っています:

- -スタック - -

-------------------

- -ヒープ - -

今、スタックでの割り当てに失敗した場合、ヒープでも失敗するはずだと思います。

だから私の質問は: スタックサイズに制限はありますか? (制限を超えると、プログラムがクラッシュしました)。または、何か不足していますか?

4

6 に答える 6

7

はい、スタックは常に制限されています。いくつかの言語/コンパイラでは、要求されたサイズを設定できます。

通常、デフォルト値 (手動で設定しない場合) は現在の languages で約 1MB です。通常は推奨されないこと (スタックに巨大な配列を割り当てるなど) を行わない限り、これで十分です。

于 2010-05-06T10:18:36.153 に答える
5

これまでのすべての回答とは対照的に、GCC を使用する Linux では (最新のすべての POSIX オペレーティング システムに当てはまると思います)、最大スタック サイズはオペレーティング システムによって強制される安全な制限であり、簡単に解除できます。

少なくとも 10 GB がスタックに割り当てられるまで関数を再帰的に呼び出し、端末で入力を待機し、その後、最大main.

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>

void grow(unsigned cur_size)
{
    if(cur_size * sizeof(int) < 10ul*1024ul*1024ul*1024ul) {
        unsigned v[1000];
        v[0] = cur_size;
        for(unsigned i = 1; i < 1000; ++i) {
            v[i] = v[i-1] + 1;
        }

        grow(cur_size + 1000);

        for(unsigned i = 0; i < 1000; ++i) {
            if(v[i] != cur_size + i)
                puts("Error!");
        }
    } else {
        putchar('#');
        getchar();
    }
}

int main()
{
    struct rlimit l;
    l.rlim_max = RLIM_INFINITY;
    l.rlim_cur = RLIM_INFINITY;
    setrlimit(RLIMIT_STACK, &l);

    grow(0);
    putchar('#');
    getchar();
}
于 2016-03-15T22:26:26.583 に答える
5

これはすべて、使用する言語とコンパイラによって異なります。ただし、たとえば C または C++ でコンパイルされたプログラムは、プログラムの起動時に固定サイズのスタックを割り当てます。スタックのサイズは通常、コンパイル時に指定できます (私の特定のコンパイラでは、デフォルトで 1 MB です)。

于 2010-05-06T09:56:17.913 に答える
2

どのプログラミング言語については言及していませんが、Delphi ではコンパイル オプションに最大スタック サイズと最小スタック サイズが含まれており、コンパイルされたすべての言語に同様のパラメータが存在すると思います。

私は確かに時々最大値を自分で増やさなければなりませんでした。

于 2010-05-06T09:58:49.903 に答える
1

はい、ほとんどの言語でスタックサイズに制限があります。たとえば、C / C ++では、不適切に記述された再帰関数(たとえば、誤ったベースケース)があると、スタックがオーバーフローします。これは、末尾再帰を無視して、関数を呼び出すたびに、スタック上のスペースを占める新しいスタックフレームが作成されるためです。これを十分に行うと、スペースが不足します。

このCプログラムをWindows(VS2008)で実行しています...

void main()
{
    main();
}

...スタックオーバーフローが発生します:

Unhandled exception at 0x004113a9 in Stack.exe: 0xC00000FD: Stack overflow.

于 2010-05-06T10:03:20.167 に答える
1

あまり良い答えではないかもしれませんが、Windows が一般的にどのようにメモリを管理しているかをもう少し詳しく見てみましょう: Windows の限界に挑む

于 2010-05-06T10:06:49.203 に答える