46

次のコードは、スタック オーバーフロー エラーを生成しています

int main(int argc, char* argv[])
{
    int sieve[2000000];
    return 0;
}

どうすればこれを回避できますか? Turbo C++ を使用していますが、コードは C のままにしたいと考えています。

編集:

アドバイスをありがとう。上記のコードは単なる例であり、実際にはサブメインではなく関数で配列を宣言しています。また、配列をゼロに初期化する必要があったため、malloc で検索したところ、calloc が私の目的に最適であることがわかりました。

Malloc/calloc には、変数を使用してサイズを宣言できるというスタックへの割り当てよりも利点もあります。

4

8 に答える 8

62

配列が大きすぎてスタックに収まりません。ヒープの使用を検討してください。

int *sieve = malloc(2000000 * sizeof(*sieve));

本当にスタック サイズを変更したい場合は、このドキュメントをご覧ください。

ヒント: - 動的に割り当てられたメモリが不要になったら、忘れずに解放してください。

于 2009-02-21T02:16:08.833 に答える
14

3 つの方法があります。

  1. malloc()他のポスターが示唆したように、配列をヒープに割り当てます-使用します。それを忘れないfree()でください(ただし、main()それほど重要ではありません-プログラムの終了時にOSがメモリをクリーンアップします)。
  2. ユニット レベルで配列を宣言します。配列はデータ セグメントに割り当てられ、誰でも見ることができます (static宣言に追加すると、ユニットへの可視性が制限されます)。
  3. 配列を次のように宣言します。staticこの場合、データ セグメントに割り当てられますが、main().
于 2009-02-21T08:42:47.233 に答える
1

これは約7MBのスタックスペースです。Visual Studioでは、/ STACK:###、###を使用して必要なサイズを反映します。本当に巨大なスタックが必要な場合(LISPなどを使用して正当な理由になる可能性があります:)、ヒープでさえ、VirtualAllocを使用するように強制する前に小さな'sh割り当てに制限されます)、PEをビルドするように設定することもできます/ LARGEADDRESSAAWARE(Visual Studioのリンカ)。ただし、これはPEヘッダーを構成して、コンパイルされたバイナリが4GBの32ビットアドレス空間全体をアドレス指定できるようにします(WOW64で実行されている場合)。真に大規模なバイナリを構築する場合は、通常、/bigobjを追加のリンカーパラメータとして構成する必要があります。

さらに多くのスペースが必要な場合は、(MSVCのリンク)/ merge:に似たものを使用することで、規則に根本的に違反する可能性があります。これにより、あるセクションを別のセクションにパックできるため、単一の共有コードにすべてのバイトを使用できます。 /dataセクション。もちろん、defファイルまたは#pgramaでSECTIONS権限を構成する必要もあります。

于 2009-02-21T03:04:06.457 に答える
1

スタックではなくヒープに割り当てたほうがよいでしょう。何かのようなもの

int main(int argc, char* argv[])
{
    int * sieve;
    sieve = malloc(20000);
    return 0;
}
于 2009-02-21T02:17:02.653 に答える
1

malloc を使用します。戻り値の型がnullでないことをすべてチェックします.nullの場合、システムには多くの値に適合するだけの十分なメモリがありません。

于 2009-02-22T06:59:56.130 に答える
0

あなたの配列は巨大です。

マシンまたは OS がそれほど多くのメモリを割り当てていないか、割り当てたくない可能性があります。


巨大な配列が絶対に必要な場合は、( を使用してmalloc(...)) 動的に割り当てることができますが、メモリ リークの危険があります。メモリを解放することを忘れないでください。

malloc の利点は、スタックではなくヒープにメモリを割り当てようとすることです (したがって、スタック オーバーフローは発生しません)。

malloc が返す値をチェックして、割り当てが成功したか失敗したかを確認できます。失敗した場合は、より小さい配列の malloc を試みてください。


別のオプションは、その場でサイズ変更できる別のデータ構造を使用することです (リンクされたリストなど)。このオプションが適切かどうかは、データをどうするかによって異なります。

さらに別のオプションは、データをその場でストリーミングして、ファイルに保存することです。このアプローチは最も遅いです。

ハード ドライブに保存する場合は、既存のライブラリ (データベース用) を使用することもできます。

于 2016-07-04T06:01:51.380 に答える
-1

alloca() を使用して、オブジェクトが実際に必要とするサイズに基づいてスタック フレームに必要なスペースを割り当てることができない理由はありますか?

それをしてもスタックが壊れる場合は、割り当てられたヒープに入れます。main() で static として宣言せず、データ セグメントに配置することを強くお勧めします。

本当にそれほど大きくする必要があり、プログラムがそれをヒープに割り当てることができない場合、プログラムはそもそもそのタイプのマシンで実行するビジネスを本当に持っていません.

何を (正確に) 達成しようとしていますか?

于 2009-02-21T08:46:13.573 に答える