トップ回答者
配列のサイズ制限

質問
-
以下の質問をSQL Serverフォーラムに質問しましたところ、Poindexter Sさんからその
旨後指摘いただきました。再度このフォーラムに質問させていただきます。
各画素の情報をファイルに取り込むために、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以外の他の有償のプログ
ラムではこのように制限は小さいのでしょうか。
以上ご教示願います。
回答
-
ローカル変数は通常はその関数内だけで使用できれば良く、かつ一時的なものを保持するのに
使用されますけれど、一時的なものだとしてもあまりにサイズが大きい場合にはローカルではなく、
ヒープ領域に変数を確保するのが普通です。
また、プログラムが起動して終了するまでの長い間の確保が必要な場合にもやはりヒープ領域を
使用します。
ローカル変数は、通常スタック領域という所に確保されますが、スタック領域は関数呼び出しの
際の引数の引き渡し等にも使われますのでここに大きい変数を取ると関数呼び出し等にも
影響します。関数の呼び出しに関しては何段階くらいまで深くなるのかは予想ができません。
なぜならライブラリとして提供されている部分の呼び出しも含まれるからです。
このようにスタック領域は大きな変数を確保するには向いていませんので
大きな変数を確保したい場合はヒープ領域と言う部分に変数を確保します。
newというキーワードで確保しているのがそれにあたります。
この辺はC++やC++/CLIで開発していくには必要な知識になりますので
きちんと理解して進まれた方が良いと思います。
すべての返信
-
(質問1への回答)
この配列はローカル変数として宣言していますよね?
ローカル変数の領域はスタックに確保されます。
スタックの初期サイズは1MByteですので(変数の型が分かりませんが)
領域が確保できずにスタックオーバーフローが発生しているようです。
「どこまで許されるか」となるとスタックの使われ方(他のローカル変数や関数の呼び出し数)などによって
変わってきますので確定的な事は言えません。
初期設定では合計1MByteを超えることはできません。
(質問2への回答)
「構成プロパティ」→「リンカ」→「システム」→「スタックのサイズの設定」を変更すれば可能です。
(質問3への回答)
他の優勝プログラムでもスタックサイズの制限はあります。
【対策】
大きな配列などはローカル変数にするのではなく、newを使って動的に確保するようにすると良いです。
newを使うとスタックではなく、ヒープに領域が確保されるため、スタックオーバーフローはでなくなります。
-
ローカル変数は通常はその関数内だけで使用できれば良く、かつ一時的なものを保持するのに
使用されますけれど、一時的なものだとしてもあまりにサイズが大きい場合にはローカルではなく、
ヒープ領域に変数を確保するのが普通です。
また、プログラムが起動して終了するまでの長い間の確保が必要な場合にもやはりヒープ領域を
使用します。
ローカル変数は、通常スタック領域という所に確保されますが、スタック領域は関数呼び出しの
際の引数の引き渡し等にも使われますのでここに大きい変数を取ると関数呼び出し等にも
影響します。関数の呼び出しに関しては何段階くらいまで深くなるのかは予想ができません。
なぜならライブラリとして提供されている部分の呼び出しも含まれるからです。
このようにスタック領域は大きな変数を確保するには向いていませんので
大きな変数を確保したい場合はヒープ領域と言う部分に変数を確保します。
newというキーワードで確保しているのがそれにあたります。
この辺はC++やC++/CLIで開発していくには必要な知識になりますので
きちんと理解して進まれた方が良いと思います。