6

VS 2010を使用しています。
このプログラムをデバッグモードで実行すると、スタックオーバーフロー例外がスローされ、ファイルchkstk.asmの99行目にブレークラインが表示されます。
ただし、リリースモードで実行すると問題ありません。
また、配列の1つのサイズを10000に減らすと、デバッグでうまく機能します。理由は何ですか?

#include <iostream>

using namespace std;
int main()
{
    char w[1000001], temp[1000001];
    cout<<"Why?"<<endl;
    return 0;
}
4

4 に答える 4

12

スタックは非常に小さく、ほとんどのシステムで約1MBであるため、大きなバッファでオーバーフローしています。これを修正するには、次のようにヒープに割り当てます。

#include <iostream>

using namespace std;
int main()
{
    char* w = new char[1000001];
    char* temp = new char[1000001];
    cout<<"Why?"<<endl;
    delete[] w;
    delete[] temp; 
    return 0;
}
于 2012-05-10T21:42:40.140 に答える
5

スタックはかなり小さい(〜1MB)。あなたはそれらの配列の膨大な数の要素でそれを埋めています。

より多くのスペースが必要な場合は、ヒープに割り当ててみてください(ポインターが行います)。

これを実装する良い方法は、ヒープに物事を内部的に格納するベクトルを使用することです。

std::vector<char> w (1000001);
std::vector<char> temp (1000001);
于 2012-05-10T21:41:02.973 に答える
5

スタックに割り当てているものが多すぎます。おそらくデバッグモードでは、さまざまな安全性チェックのためにスタックがより占有されているか、そのような問題を早期に検出できるように意図的に小さくなっています。とにかく、配列を少し大きくすると、リリースモードでもスタックオーバーフローがトリガーされます(コンパイラがそれらを完全に最適化しない限り)。

ここでの問題の根本は、スタックに大きなものを割り当てるべきではないということです。これは、サイズが非常に制限されており(VC++を使用するWindowsではデフォルトで1MB)、小さなバッファー/オブジェクトにのみ使用する必要があります。大きな割り当てを行う必要がある場合は、ヒープ上で(new/mallocを使用して)割り当てます。メモリリークを回避するために、できればスマートポインタを使用します。

于 2012-05-10T21:41:59.907 に答える
4

自動ストレージ内のアレイはスタックに割り当てられます。スタックスペースには限りがあります。スタック上のスペースが自動変数を割り当てるのに不十分な場合、スタックオーバーフロー例外が発生します。

大きな配列が必要な場合は、代わりに静的または動的な割り当てを使用してください。

静的割り当ての場合、宣言を外部に移動しmain()ます。

動的割り当ての場合は、次のコードを使用します。

char *w = new char[1000001], *temp = new char[1000001];
// Work with w and temp as usual, then
delete[] w;
delete[] temp;

最後に、プレーン配列の代わりに標準配列を使用することを検討してstd::arrayください。サイズ変更が必要ない場合は、より適切な配列です(スタックに割り当てられ、この問題は解決されません)。アレイstd::stringを置き換えるのにも適しています。char

于 2012-05-10T21:41:37.853 に答える