dポイントプレゼントキャンペーン実施中!

大きめの配列(2Mくらい)を宣言するとスタックオーバーフローのエラーが発生します。で、配列をstaticにしたらエラーが発生しなくなりました。

なんとなく、初期に大きいバッファを確保するならOKで実行時に確保するとNGなのかな~と思っているのですが、このあたりのことを教えていただけないでしょうか。

なんとなく2Mくらいでオーバーフローが出るのも納得できません。

よろしくお願いします。

環境:VC++ .Net + winXP

A 回答 (4件)

2Mの配列を宣言というと



void method(){
char a[20000000];
....
}

という感じでしょうか。

C/C++言語のメモリは、大きく4つに分かれます。
(1)コード(プログラム)が記録されている領域。
(2)静的記憶領域。(文字列リテラル等が記憶されている領域)
(3)スタック領域。
(4)ヒープ領域。

(1)、(2)はこの際関係ないので置いといて、
関数やメソッドの中でふつうに(staticをつけずに)
変数を宣言したとき、そのデータはスタック領域に置かれます。

これに対し、関数の外(グローバル変数)の変数、
static宣言した変数、malloc()で確保したメモリ、
newで作成したオブジェクトは、
ヒープ領域に置かれます。

スタック領域とヒープ領域を比べた場合、
ヒープ領域の方がはるかに大きいのです。
その代わり、スタックの方が効率的にアクセスできるようになっています。
スタック領域は一等地なのです。
山手線沿線に飛行場が作れないのと同じで、
スタックにあまり大きなメモリを確保することは出来ません。

なので、関数・メソッドの中の非static変数(自動変数)に
大きなメモリ領域を確保するのはタブーになっています。
    • good
    • 0
この回答へのお礼

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

ありがとうございました。

お礼日時:2006/05/28 22:02

コンパイラ、リンカのオプションに「スタック サイズの設定」というのがありませんか?


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

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

ありがとうございました。

お礼日時:2006/05/28 21:57

スレッド内で使える「スタックサイズ」には制限があります。


上記を自動変数で確保しているなら「スタックオーバフロー」します。
C++の場合は、new で確保してください。
    • good
    • 0
この回答へのお礼

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

newで確保するほうが良いのでしょうか・・。

お礼日時:2006/05/28 22:08

UNIXなら、1プロセスが確保できるメモリがカーネルパラメータで定義されてるのですが。



windowsは、うーん、msdn探してみるとかですか。

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

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!