オブジェクトの最大可能サイズは、C 実装が対象とするアーキテクチャのメモリ マップによって決まります (原則として、および/またはその他の実装の詳細ですが、実際にはそれが行われます)。
現在使用されているほとんどのシステムを含む、いわゆる「フラット」メモリ モデルでは、これは、オブジェクトがほぼアドレス空間全体のサイズになる可能性があることを意味します (リソースが許す場合) size_t
。ポインター。アドレス空間が 32 ビットの場合、オブジェクトの各バイトは異なるアドレスを持つため、明らかに 2^32-1 バイト (-1 はヌル ポインター値が 1 つのアドレスを「使い果たす」ため) よりも大きなオブジェクトを持つことはできません。どのオブジェクトのアドレスでもないことが保証されています)。
セグメント化されたメモリ アーキテクチャでは、C 実装が 2^32 バイトのスペースをアドレス指定できる場合がありますが、1 つのオブジェクトが複数の 16 ビット セグメントにまたがることは許可されていないため、原則size_t
として 16 ビット型になる可能性があります。
malloc
さらに言えば、C の実装者は、2^24-1 バイトを超えるブロックを決して返さないという、全くのいたずらで、任意の制限を に設定することが許可されています。そのサイズの静的オブジェクトまたは自動オブジェクトを防止するというコンパイラーの同じ制限により、size_t
ポインターが大きくても24ビット型になる可能性があります。
楽しみのためだけにこれを行う実装者がいないことを願っていますが、その 24 ビット制限が存在する実際的な理由があるかもしれません。たとえば、実装が動的割り当てに最大 16MB の RAM を使用し、静的オブジェクトに 16MB の別の制限を使用する場合、16MB を超えるオブジェクトはありませんが、ポインターは少なくとも 25 ビットである必要があります。その場合でも、実装者がわざわざ24 ビット型を作成size_t
するとは思えません。おそらく、それでも 32 ビットになるでしょう。しかし、標準では、実装者が最適なものを選択できます。
「最大のデータオブジェクトのサイズにアクセスするには十分ですが、それ以上ではありません」とあなたは言います。これ以上大きくしてはいけないというのは真実ではありません。たとえば、プラットフォームの技術的な制限により、オブジェクトが 2^31-1 バイトを超えることはできないというsize_t
場合、31 ビット型である必要はありません。必要なのは十分な大きさだけであるため、32 ビット型を使用できます。