C++ の size_t と int の違いは何ですか?

親しみやすいウィキペディアより:

また、なぜ size_t が重要なのかを確認してください


size_t は、サイズを表すために使用される型です (その名前が示すように)。そのプラットフォーム (および場合によっては実装) に依存するため、この目的にのみ使用する必要があります。明らかに、サイズを表す size_t は符号なしです。 malloc、sizeof、およびさまざまな文字列操作関数を含む多くの stdlib 関数は、size_t をデータ型として使用します。

int はデフォルトで署名され、そのサイズもプラットフォームに依存しますが、ほとんどの最新のマシンでは固定の 32 ビットになります (64 ビット アーキテクチャでは size_t は 64 ビットですが、これらのアーキテクチャでは int は 32 ビット長のままです)。 /P>

要約すると、オブジェクトのサイズを表すには size_t を使用し、それ以外の場合は int (または long) を使用します。


size_t type は sizeof の符号なし整数型として定義されます オペレーター。現実の世界では、int をよく見かけます。 (下位互換性のため) 32 ビットとして定義されていますが、size_t 64 ビット プラットフォームで 64 ビットとして定義されます (したがって、サイズが 4 GiB を超える配列と構造体を宣言できます)。 long int の場合 も 64 ビットです。これは LP64 規則と呼ばれます。 long int の場合 32 ビットですが、long long int ポインターは 64 ビット、つまり LLP64 です。逆に、速度を上げるために 64 ビット命令を使用し、メモリを節約するために 32 ビット ポインターを使用するプログラムを取得することもできます。また、int 署名されており、size_t 署名されていません。

歴史的に、アドレスが int のネイティブ サイズよりも広いまたは短い他のプラットフォームが多数ありました。 .実際、1970 年代から 80 年代初頭にかけて、これは一般的でした。一般的な 8 ビット マイクロコンピュータはすべて、8 ビット レジスタと 16 ビット アドレスを備えていました。また、16 ビットから 32 ビットへの移行によって、レジスタより広いアドレスを持っていました。 MS-DOS 用の Borland Turbo C に関する質問を時々ここで目にします。この巨大メモリ モードでは、20 ビット アドレスが 16 ビット CPU の 32 ビットに格納されていました (ただし、80386 の 32 ビット命令セットをサポートできます)。 Motorola 68000 には、32 ビットのレジスタとアドレスを持つ 16 ビットの ALU がありました。 15 ビット、24 ビット、または 31 ビットのアドレスを持つ IBM メインフレームがありました。組み込みシステムでは、ALU とアドレスバスのサイズが異なることもわかります。

いつでも int size_t より小さい 、および非常に大きなファイルまたはオブジェクトのサイズまたはオフセットを unsigned int に保存しようとしました 、オーバーフローしてバグが発生する可能性があります。 int で 、負の数を取得する可能性もあります。 int の場合 または unsigned int より広い場合、プログラムは正しく実行されますが、メモリが浪費されます。

移植性が必要な場合は、通常、目的に合った正しい型を使用する必要があります。多くの人は、符号なしの代わりに符号付きの数学を使用することを推奨します (1U < -3 のような厄介で微妙なバグを避けるため) )。そのために、標準ライブラリでは ptrdiff_t を定義しています。 <stddef.h> で ポインターを別のポインターから減算した結果の符号付き型として。

つまり、回避策として、すべてのアドレスとオフセットを INT_MAX に対して境界チェックすることが考えられます。 および 0 のいずれか または INT_MIN 必要に応じて、符号付きと符号なしの量の比較に関するコンパイラの警告をオンにして、見落としがある場合に備えます。いずれにせよ、常に、常に、C での配列アクセスのオーバーフローを常にチェックする必要があります。