配列のサイズ制限
質問
2007年9月20日木曜日 11:32
以下の質問をSQL Serverフォーラムに質問しましたところ、Poindexter Sさんからその
旨後指摘いただきました。再度このフォーラムに質問させていただきます。
画像の処理プログラムを作成しています。68歳の素人上がりで奮闘しています。
各画素の情報をファイルに取り込むために、dimension[1000][1000]を宣言しましたとこ
ろ、Debugの途中「Igo.exe(プログラム名) の 0x00411e17 でハンドルされていない
例外が発生しました: 0xC00000FD: Stack overflow」のエラーメッセージがでて止りま
す。dim[500][500]はOK,dim[510][510]では1000の場合と同様に止ります。
(質問1)現状では、dimのサイズはどこまで許されるのでしょうか。
(質問2)Microsoft Visual Studio 2005 Express editionの設定でサイズを大きく
できるのでしょうか。
(質問3)Microsoft Visual Studio 2005 Express edition以外の他の有償のプログ
ラムではこのように制限は小さいのでしょうか。
以上ご教示願います。
すべての返信 (5)
2007年9月25日火曜日 4:36 ✅回答済み
ローカル変数は通常はその関数内だけで使用できれば良く、かつ一時的なものを保持するのに
使用されますけれど、一時的なものだとしてもあまりにサイズが大きい場合にはローカルではなく、
ヒープ領域に変数を確保するのが普通です。
また、プログラムが起動して終了するまでの長い間の確保が必要な場合にもやはりヒープ領域を
使用します。
ローカル変数は、通常スタック領域という所に確保されますが、スタック領域は関数呼び出しの
際の引数の引き渡し等にも使われますのでここに大きい変数を取ると関数呼び出し等にも
影響します。関数の呼び出しに関しては何段階くらいまで深くなるのかは予想ができません。
なぜならライブラリとして提供されている部分の呼び出しも含まれるからです。
このようにスタック領域は大きな変数を確保するには向いていませんので
大きな変数を確保したい場合はヒープ領域と言う部分に変数を確保します。
newというキーワードで確保しているのがそれにあたります。
この辺はC++やC++/CLIで開発していくには必要な知識になりますので
きちんと理解して進まれた方が良いと思います。
2007年9月20日木曜日 12:50
(質問1への回答)
この配列はローカル変数として宣言していますよね?
ローカル変数の領域はスタックに確保されます。
スタックの初期サイズは1MByteですので(変数の型が分かりませんが)
領域が確保できずにスタックオーバーフローが発生しているようです。
「どこまで許されるか」となるとスタックの使われ方(他のローカル変数や関数の呼び出し数)などによって
変わってきますので確定的な事は言えません。
初期設定では合計1MByteを超えることはできません。
(質問2への回答)
「構成プロパティ」→「リンカ」→「システム」→「スタックのサイズの設定」を変更すれば可能です。
(質問3への回答)
他の優勝プログラムでもスタックサイズの制限はあります。
【対策】
大きな配列などはローカル変数にするのではなく、newを使って動的に確保するようにすると良いです。
newを使うとスタックではなく、ヒープに領域が確保されるため、スタックオーバーフローはでなくなります。
2007年9月21日金曜日 0:57
ご教示有り難うございます。
早速、スタックサイズの変更を試みます。結果は又ご報告いたします。
shun
2007年9月21日金曜日 2:08
外池と申しますが・・・、
C.Johnさんが示された「対策」に沿ったほうが良いように思われますが・・・。スタックサイズの変更は泥沼になると思います。一度動くようになっても、プログラムの変更を重ねると(というか、書き進めていくと)、あるいは、取り扱う画像のサイズを大きくすると、同じエラーが再現する可能性が非常に高いと思います。
スタック領域、ヒープ領域の違いをご理解頂ければ、対策はほぼ自明になるのですが・・・。
老婆心ながら。
2007年10月4日木曜日 12:39
丁寧なご指導有り難うございます。
当面スタックサイズを変えて動きましたが、仰せの通りヒープを勉強したいと思います。
有り難うございます。
Snonaka