• ベストアンサー

C++のスタック管理

大きめの配列(2Mくらい)を宣言するとスタックオーバーフローのエラーが発生します。で、配列をstaticにしたらエラーが発生しなくなりました。 なんとなく、初期に大きいバッファを確保するならOKで実行時に確保するとNGなのかな~と思っているのですが、このあたりのことを教えていただけないでしょうか。 なんとなく2Mくらいでオーバーフローが出るのも納得できません。 よろしくお願いします。 環境:VC++ .Net + winXP

質問者が選んだベストアンサー

  • ベストアンサー
  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.3

2Mの配列を宣言というと void method(){ char a[20000000]; .... } という感じでしょうか。 C/C++言語のメモリは、大きく4つに分かれます。 (1)コード(プログラム)が記録されている領域。 (2)静的記憶領域。(文字列リテラル等が記憶されている領域) (3)スタック領域。 (4)ヒープ領域。 (1)、(2)はこの際関係ないので置いといて、 関数やメソッドの中でふつうに(staticをつけずに) 変数を宣言したとき、そのデータはスタック領域に置かれます。 これに対し、関数の外(グローバル変数)の変数、 static宣言した変数、malloc()で確保したメモリ、 newで作成したオブジェクトは、 ヒープ領域に置かれます。 スタック領域とヒープ領域を比べた場合、 ヒープ領域の方がはるかに大きいのです。 その代わり、スタックの方が効率的にアクセスできるようになっています。 スタック領域は一等地なのです。 山手線沿線に飛行場が作れないのと同じで、 スタックにあまり大きなメモリを確保することは出来ません。 なので、関数・メソッドの中の非static変数(自動変数)に 大きなメモリ領域を確保するのはタブーになっています。

pokapoka1980
質問者

お礼

まさに知りたいことで、勉強になります。 スタックとヒープがごっちゃになっていました。 回答いただいたようなことだったんですね。 ありがとうございました。

その他の回答 (3)

  • neko3839
  • ベストアンサー率37% (100/269)
回答No.4

コンパイラ、リンカのオプションに「スタック サイズの設定」というのがありませんか? VC++.NET は未確認ですが、VC++ 6.0はMSDNのCD-ROMを見るとデフォルト値が1MBとされているようです。 コンパイラ、リンカのオプションでスタックサイズを大きめにするのも1つの対応ではあります。 C++であればnew演算子を使った方が良いと思います。

pokapoka1980
質問者

お礼

オプションがあるんですね。 ちょっと今探しても見つからなかったのですが、 6.0にあるならNETにもあると思いますのであとでもう少し探して見ます。 ありがとうございました。

  • neko3839
  • ベストアンサー率37% (100/269)
回答No.2

スレッド内で使える「スタックサイズ」には制限があります。 上記を自動変数で確保しているなら「スタックオーバフロー」します。 C++の場合は、new で確保してください。

pokapoka1980
質問者

お礼

mallocやnewでの確保も考えたのですが、4次元の配列なので、のちのち(クラスヘッダーを見たときに)分かりやすいと思い、配列での宣言としていました。 newで確保するほうが良いのでしょうか・・。

  • t_nojiri
  • ベストアンサー率28% (595/2071)
回答No.1

UNIXなら、1プロセスが確保できるメモリがカーネルパラメータで定義されてるのですが。 windowsは、うーん、msdn探してみるとかですか。

参考URL:
http://docs.hp.com/ja/B3920-90093/ch08s05.html