none
配列のサイズ制限 RRS feed

  • 質問

  •  

    以下の質問を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以外の他の有償のプログ
    ラムではこのように制限は小さいのでしょうか。
    以上ご教示願います。
    2007年9月20日 11:32

回答

  • ローカル変数は通常はその関数内だけで使用できれば良く、かつ一時的なものを保持するのに

    使用されますけれど、一時的なものだとしてもあまりにサイズが大きい場合にはローカルではなく、

    ヒープ領域に変数を確保するのが普通です。

    また、プログラムが起動して終了するまでの長い間の確保が必要な場合にもやはりヒープ領域を

    使用します。

    ローカル変数は、通常スタック領域という所に確保されますが、スタック領域は関数呼び出しの

    際の引数の引き渡し等にも使われますのでここに大きい変数を取ると関数呼び出し等にも

    影響します。関数の呼び出しに関しては何段階くらいまで深くなるのかは予想ができません。

    なぜならライブラリとして提供されている部分の呼び出しも含まれるからです。

    このようにスタック領域は大きな変数を確保するには向いていませんので

    大きな変数を確保したい場合はヒープ領域と言う部分に変数を確保します。

    newというキーワードで確保しているのがそれにあたります。

     

    この辺はC++やC++/CLIで開発していくには必要な知識になりますので

    きちんと理解して進まれた方が良いと思います。

     

    2007年9月25日 4:36

すべての返信

  • (質問1への回答)

    この配列はローカル変数として宣言していますよね?

    ローカル変数の領域はスタックに確保されます。

    スタックの初期サイズは1MByteですので(変数の型が分かりませんが)

    領域が確保できずにスタックオーバーフローが発生しているようです。

    「どこまで許されるか」となるとスタックの使われ方(他のローカル変数や関数の呼び出し数)などによって

    変わってきますので確定的な事は言えません。

    初期設定では合計1MByteを超えることはできません。

     

    (質問2への回答)

    「構成プロパティ」→「リンカ」→「システム」→「スタックのサイズの設定」を変更すれば可能です。

     

    (質問3への回答)

    他の優勝プログラムでもスタックサイズの制限はあります。

     

    【対策】

    大きな配列などはローカル変数にするのではなく、newを使って動的に確保するようにすると良いです。

    newを使うとスタックではなく、ヒープに領域が確保されるため、スタックオーバーフローはでなくなります。

    2007年9月20日 12:50
  •  

    ご教示有り難うございます。

    早速、スタックサイズの変更を試みます。結果は又ご報告いたします。

    shun

    2007年9月21日 0:57
  • 外池と申しますが・・・、

     

    C.Johnさんが示された「対策」に沿ったほうが良いように思われますが・・・。スタックサイズの変更は泥沼になると思います。一度動くようになっても、プログラムの変更を重ねると(というか、書き進めていくと)、あるいは、取り扱う画像のサイズを大きくすると、同じエラーが再現する可能性が非常に高いと思います。

     

    スタック領域、ヒープ領域の違いをご理解頂ければ、対策はほぼ自明になるのですが・・・。

     

    老婆心ながら。

     

    2007年9月21日 2:08
  • ローカル変数は通常はその関数内だけで使用できれば良く、かつ一時的なものを保持するのに

    使用されますけれど、一時的なものだとしてもあまりにサイズが大きい場合にはローカルではなく、

    ヒープ領域に変数を確保するのが普通です。

    また、プログラムが起動して終了するまでの長い間の確保が必要な場合にもやはりヒープ領域を

    使用します。

    ローカル変数は、通常スタック領域という所に確保されますが、スタック領域は関数呼び出しの

    際の引数の引き渡し等にも使われますのでここに大きい変数を取ると関数呼び出し等にも

    影響します。関数の呼び出しに関しては何段階くらいまで深くなるのかは予想ができません。

    なぜならライブラリとして提供されている部分の呼び出しも含まれるからです。

    このようにスタック領域は大きな変数を確保するには向いていませんので

    大きな変数を確保したい場合はヒープ領域と言う部分に変数を確保します。

    newというキーワードで確保しているのがそれにあたります。

     

    この辺はC++やC++/CLIで開発していくには必要な知識になりますので

    きちんと理解して進まれた方が良いと思います。

     

    2007年9月25日 4:36
  • 丁寧なご指導有り難うございます。

    当面スタックサイズを変えて動きましたが、仰せの通りヒープを勉強したいと思います。

    有り難うございます。

    Snonaka

    2007年10月4日 12:39