web-dev-qa-db-ja.com

大きなアレイサイズでのセグメンテーションフォールト

次のコードは、2Gbマシンで実行するとセグメンテーションエラーが発生しますが、4GBマシンでは動作します。

int main()
{
   int c[1000000];
   cout << "done\n";
   return 0;
}

配列のサイズはわずか4Mbです。 C++で使用できる配列のサイズに制限はありますか?

100
Mayank

ここでスタックオーバーフローが発生している可能性があります。配列が大きすぎて、プログラムのスタックアドレス空間に収まりません。

ヒープに配列を割り当てる場合は、マシンに十分なメモリがあると仮定して問題ありません。

int* array = new int[1000000];

ただし、これには配列をdelete[]する必要があることに注意してください。より良い解決策は、std::vector<int>を使用し、1000000要素にサイズ変更することです。

113
Charles Salvia

CまたはC++では、通常、ローカルオブジェクトはスタックに割り当てられます。スタックが処理できる以上の大きな配列をスタックに割り当てているため、 stackoverflow。 を取得しています。

スタック上のローカルに割り当てないで、代わりに他の場所を使用してください。これは、オブジェクトglobalを作成するか、グローバルheapに割り当てることで実現できます。他のコンパイル単位を使用しない場合、グローバル変数は問題ありません。これが偶然に発生しないようにするには、静的ストレージ指定子を追加します。そうでない場合は、ヒープを使用します.

これにより、ヒープの一部であるBSSセグメントに割り当てられます。

static int c[1000000];
int main()
{
   cout << "done\n";
   return 0;
}

これにより、ヒープの一部であるDATAセグメントに割り当てられます。

int c[1000000] = {};
int main()
{
   cout << "done\n";
   return 0;
}

これにより、ヒープ内の指定されていない場所に割り当てられます。

int main()
{
   int* c = new int[1000000];
   cout << "done\n";
   return 0;
}
50
Gunther Piez

また、ほとんどのUNIXおよびLinuxシステムで実行している場合、次のコマンドで一時的にスタックサイズを増やすことができます。

ulimit -s unlimited

しかし、注意してください、メモリは限られたリソースであり、大きな力には大きな責任が伴います:)

10
RSFalcon7

スタックに配列を保存するためです。ヒープに保存する必要があります。 このリンク を参照して、ヒープとスタックの概念を理解してください。

2
Narek

この場合、あなたの配列はスタックに割り当てられています。allocを使用して同じサイズの配列を割り当てようとします。

2
rerun