PHP中文网2017-04-17 14:57:49
長い時間を経て、ついに答えが見つかりました。
まず、配列の最大長を決定したい場合は、そのデータ型を知る必要があります。したがって、配列のデータ型は制限の 1 つです。要因。データ型が異なれば要素のサイズも異なるためです。明らかに (int
が 4 バイト、char
が 1 バイトであると仮定します)、データ型 char
の配列の最大長は、 int
の配列の 4 倍です。
さらに、サイズ (サイズ) のデータ型、つまり配列添字のデータ型が実際には制限要因であると考えるのは難しくありません。 。 C/C++ では、配列の添字の型は std::size_t
であるため、配列のサイズは size_t
で表現できるサイズを超えることはできません。このデータ型は、ライブラリ ファイル stdio.h
から typedef
で宣言されます。32 ビット プログラムの場合、64 ビットの場合は unsighed int
として定義されます。ビット プログラムは、unsigned long
として定義されます。前者が表現できる最大サイズは 2^32-1、後者は 2^64-1 です。
次に物理メモリのサイズについて考えてみました。当然のことですが、プログラムの実行中に物理メモリのサイズを超えると、プログラムはすぐにクラッシュします。
上記の点は比較的一般的な制限です。巨視的な制限要因という、より高いレベルの表現に変更してみましょう。以下に、 いくつかの微視的な制限要因を紹介します。
配列を割り当てるには、静的割り当てと動的割り当てという 2 つの方法があることは誰もが知っているはずです。具体的に言うと、配列宣言の位置によって配列をローカル配列とグローバル配列に分けることができます。このように議論すると複雑になりますが、 配列を暫定的に 4 つのカテゴリに分けることができます(このように分けているのは筆者だけです。そのような正式な分類があるかどうかは知りません)。 : 静的に割り当てられたローカルstrong>配列、 動的に割り当てられたローカル配列、 静的に割り当てられたグローバル配列、 動的に割り当てられたグローバル配列。
最初のタイプの配列割り当てではスタック上のスペースが使用されるため、静的割り当てによって取得されるローカル配列のサイズはスタックのサイズに制限されます。具体的には、配列が配置されている関数のスタック フレームのサイズです。もちろん、スタック フレームのサイズはスタックのサイズを超えてはなりません。コンパイラの使用に慣れている場合、またはコンパイラのドキュメントを読んだことがある場合は、スタック フレーム サイズの制限を調整する方法を知っているはずです。 WINDOWS では、スタック サイズは 2M です (1M であるという説もあります。つまり、これはコンパイル時に決定される定数です)。適用されたスペースがスタックの残りのスペースを超えると、オーバーフローが発生します。
2 番目の配列と 4 番目の配列は同じカテゴリに分類されるべきだと思います。基本的に、それらはヒープ上にスペースを割り当てるため、そのサイズはヒープのサイズによって制限されます。ヒープは不連続なメモリ領域であり、ヒープのサイズはコンピュータ システムの有効な仮想メモリによって制限されるため、一般にヒープのサイズは比較的大きくなります。
3 番目の配列タイプについては、静的ストレージ領域にメモリ空間を割り当てることがわかっているため、サイズは BSS (Block Started by Symbol とも呼ばれる) 静的ストレージ領域のサイズによって自然に制限されます。 )、アセンブリ言語では、データ セグメントとも呼ばれます。現時点では、静的ストレージ領域のサイズ制限についてはあまり明確ではありません。自分のコンピューター (Core i3-3110M、8GB メモリ) で実験を行ったところ、割り当て可能な最大サイズはストレージ領域の約 1/2 であることがわかりました。残りのメモリ。インターネット上には「定数はそれだけ大きい」という格言がありますが、それはまだ検証されていません。
注: スタック フレームの概念については、『コンピュータ システムの詳細』またはコンピュータ アーキテクチャに関するその他の情報を参照してください。
すでにブログにまとめられています: C++ における配列の最大長。
天蓬老师2017-04-17 14:57:49
スタック上の配列の場合、サイズはスタック サイズに制限されます (4MB であることに注意してください)。ヒープの場合、理論的には、オペレーティング システムがプロセスに使用を許可する最大メモリから、メモリ内でコードや定数などが占有する領域を差し引いたものを使用できます。しかし、それらをすべて使用しなければならない場合、プログラムはすぐにクラッシュするでしょう。
PHP中文网2017-04-17 14:57:49
これは、CPU のアドレッシング ビット幅とオペレーティング システムのアドレッシング モードに関係します。
仮想メモリのフラット アドレッシング モードの場合
32 ビット ポインターのアドレス範囲は 2^32 = 4GB です