10^9 の数値 (long int) を格納できる配列を作成したいと考えています。これを実行しようとすると、コンパイラがクラッシュします。C++ で許可されている配列の最大サイズは何ですか。これを動的に行うと、同じ結果が得られます。問題。達成しようとしているタスクをどのように達成できますか? ありがとう、助けていただければ幸いです。
4 に答える
配列の最大サイズは、格納するデータ (およびそれらのインデックスに使用できる整数) によって異なります。
したがって、32 ビット システムでは、運が良ければ最大 2³² の要素しかインデックス化できません。これは 10⁹ を少し上回ります。64 ビット システムでは、10¹⁹ を少し上回る 2⁶⁴ 要素にインデックスを付けることができます。これは基本的に配列の最大サイズです。実際の仮想アドレス空間ははるかに小さい可能性があるため、インデックスを作成できるということは、実際にオペレーティング システムからそれほど多くを取得できることを意味するものではありません。Linux では、約の仮想アドレス空間。64 ビットのプロセスごとに 64 テラバイト (2⁴² バイト) を使用できます。
しかし、実際にこれを割り当てようとすると、それだけのバイト数が必要になります。したがって、long int
おそらく 64 ビットのサイズの配列を割り当てようとすると、8 ギガバイトのメモリが必要になります。
32 ビット システムでは、これは不可能です。64 ビット システムでは、その量の RAM とスワップ スペースが機能する必要があります。
32 ビット システムまたは十分なメモリのない 64 ビット システムを使用している場合は、メモリ不足エラーが発生します。これがおそらく、表示される動作の理由です。
また、実行可能ファイルの .data セクションで静的に配列を作成しようとすると、実行可能ファイルが 8 GB になる可能性があり、ファイルシステムの制限 (fat32 の誰か?) に遭遇する可能性があります。また、コンパイラはおそらくデータ量でチョークします (32 ビットでは、おそらくクラッシュします)。
スタックに割り当てている場合 (これは、静的にサイズ設定されたローカル変数配列として)、特定のオペレーティング システムのスタック制限にも遭遇します。
10^9 の long の配列は通常、少なくとも 4GB のメモリを占有しますが、これはすべての 32 ビット システムではすでに法外な量です。
64 ビット システムでそれだけの量のメモリを使用できる場合でも、次のようにスタックに 4 GB を割り当てることは期待できません。
void foo() {
long arr[1000000000]; // stack size is a typically few MBs!
}
コンパイラのクラッシュではなく、メモリのクラッシュ (メモリ不足など) だと思います。たとえば、Windows 32 ビットでは、最大で 2^32 ビットのメモリ空間を使用できます。これは 10^9* より小さいです。 64 であるため、メモリ例外が発生します。ファイルから小さな部分をページングしてメモリにロードすることで、それを使用できます。
編集: Tobias Langner がコメントで述べたように、コンパイラもこのエラーを発生させる可能性がありますが、元の問題はメモリにあります。
配列を作りたい
本当に配列が必要ですか? つまり、整数を 1 つのメモリ ブロックに格納する必要がありますか、それとも単にインデックスでアクセスしたいだけですか? メモリ レイアウトは気にしないが、要素にすばやくアクセスしたい場合は、 を使用する必要がありますstd::deque
。メモリの 1 つのチャンクを割り当てる代わりに、数値を多数の小さなチャンクに格納するので、すべての数値をまとめて格納するのに十分なメモリがあれば問題ありません。