プログラム内のスタックサイズの画定について
昨日子豚登山のテーマで配列容量が大きすぎるという問題に遭遇しましたが、今日はまとめました.
まず、Slyarの記事「C言語グローバル変数とローカル変数のサイズ制限」を参考に直接貼り付けます.
コンパイル実行後にオーバーフローエラーが見つかりました.
コンパイルが正常に実行されます.
理由を説明する前に、C/C++でコンパイルされたプログラムが消費するメモリをいくつかの部分に分けて見てみましょう.
1、スタック領域(stack sagment):コンパイラによって自動的に割り当てられて解放され、関数のパラメータの値、局所変数の値などを格納する.Windowsでは、スタックは低アドレスに拡張されたデータ構造で、連続したメモリの領域です.スタックトップのアドレスとスタックの最大容量はシステムで予め定められており、Windowsではスタックの大きさは1 Mであり、申請したスペースがスタックの残りのスペースを超えるとstack overflowが提示される.したがって、スタックから得られる空間は小さい.
2、ヒープゾーン(heap sagment):一般的にプログラマーによってリリースが割り当てられ、プログラマーがリリースされない場合、プログラム終了時にシステムによって回収される可能性がある.データ構造のスタックとは異なります.スタックは高アドレスに拡張されたデータ構造であり、不連続なメモリ領域である.これは,システムがチェーンテーブルで格納する空きメモリアドレスであるため,当然不連続であり,チェーンテーブルの遍歴方向は低アドレスから高アドレスである.スタックのサイズは、コンピュータシステムで有効な仮想メモリに制限されます.このことから,スタックが得られる空間は比較的柔軟であり,比較的大きいことが分かる.
3、グローバル領域(静的領域):グローバル変数と静的変数の記憶領域は一緒であり、プログラム終了後にシステムから解放される.データ領域のサイズはシステムによって制限され、一般的に大きく、Windows 32ビットオペレーティングシステムでは2 GBに達することができるため、オーバーフローはありません.32ビットオペレーティングシステムのアドレス空間は4 Gであるが、プログラムに残されたのは2 Gだけであり、他の2 Gがオペレーティングシステムに残されているため、自用されている.Windows Server 2003がサポートできるグローバル変数空間は3 Gに達する.
4、文字定数領域:定数文字列はここに置いてあり、プログラムが終わったらシステムから解放される.
5、プログラムコード領域:関数体のバイナリコードを保存する.
以上のように、局所変数空間は小さく、a[10000000]を開くとスタックオーバーフローを引き起こす.一方、グローバル変数空間は一般的に大きいため、1 Mを超える変数はできるだけグローバル変数または静的変数として宣言される.
Cプログラミングを使用する場合、コンパイラの設定でスタックのサイズを設定できます.
VC6.0でスタックサイズを変更する方法:
1). 「Project->Settings」を選択します. 2). 「リンク」を選択します. 3. 「Category」の「Output」を選択します. 4. 「Stack allocations」の「Reserve:」におけるスタックのサイズは、例えば、32768で下図のようになります.
VS 2010でスタックサイズを設定する方法は、次のとおりです.
1). 「プロジェクト->プロパティ」を選択します.2). 「リンク」を選択します.3.「システム」を選択します.4.スタック予約サイズでのスタックのサイズ(例:32768).
次の図に示します.
まず、Slyarの記事「C言語グローバル変数とローカル変数のサイズ制限」を参考に直接貼り付けます.
#include
int main(){
int a[1000000];//
return 0;
}
コンパイル実行後にオーバーフローエラーが見つかりました.
#include
int a[1000000];//
int main(){
return 0;
}
コンパイルが正常に実行されます.
理由を説明する前に、C/C++でコンパイルされたプログラムが消費するメモリをいくつかの部分に分けて見てみましょう.
1、スタック領域(stack sagment):コンパイラによって自動的に割り当てられて解放され、関数のパラメータの値、局所変数の値などを格納する.Windowsでは、スタックは低アドレスに拡張されたデータ構造で、連続したメモリの領域です.スタックトップのアドレスとスタックの最大容量はシステムで予め定められており、Windowsではスタックの大きさは1 Mであり、申請したスペースがスタックの残りのスペースを超えるとstack overflowが提示される.したがって、スタックから得られる空間は小さい.
2、ヒープゾーン(heap sagment):一般的にプログラマーによってリリースが割り当てられ、プログラマーがリリースされない場合、プログラム終了時にシステムによって回収される可能性がある.データ構造のスタックとは異なります.スタックは高アドレスに拡張されたデータ構造であり、不連続なメモリ領域である.これは,システムがチェーンテーブルで格納する空きメモリアドレスであるため,当然不連続であり,チェーンテーブルの遍歴方向は低アドレスから高アドレスである.スタックのサイズは、コンピュータシステムで有効な仮想メモリに制限されます.このことから,スタックが得られる空間は比較的柔軟であり,比較的大きいことが分かる.
3、グローバル領域(静的領域):グローバル変数と静的変数の記憶領域は一緒であり、プログラム終了後にシステムから解放される.データ領域のサイズはシステムによって制限され、一般的に大きく、Windows 32ビットオペレーティングシステムでは2 GBに達することができるため、オーバーフローはありません.32ビットオペレーティングシステムのアドレス空間は4 Gであるが、プログラムに残されたのは2 Gだけであり、他の2 Gがオペレーティングシステムに残されているため、自用されている.Windows Server 2003がサポートできるグローバル変数空間は3 Gに達する.
4、文字定数領域:定数文字列はここに置いてあり、プログラムが終わったらシステムから解放される.
5、プログラムコード領域:関数体のバイナリコードを保存する.
以上のように、局所変数空間は小さく、a[10000000]を開くとスタックオーバーフローを引き起こす.一方、グローバル変数空間は一般的に大きいため、1 Mを超える変数はできるだけグローバル変数または静的変数として宣言される.
Cプログラミングを使用する場合、コンパイラの設定でスタックのサイズを設定できます.
VC6.0でスタックサイズを変更する方法:
1). 「Project->Settings」を選択します. 2). 「リンク」を選択します. 3. 「Category」の「Output」を選択します. 4. 「Stack allocations」の「Reserve:」におけるスタックのサイズは、例えば、32768で下図のようになります.
VS 2010でスタックサイズを設定する方法は、次のとおりです.
1). 「プロジェクト->プロパティ」を選択します.2). 「リンク」を選択します.3.「システム」を選択します.4.スタック予約サイズでのスタックのサイズ(例:32768).
次の図に示します.