web-dev-qa-db-ja.com

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

いくつかのC++の例では、単純なintを使用するタイプsize_tの使用を確認しています。違いは何ですか?また、なぜsize_tが優れているのでしょうか?

151
tunnuz

フレンドリーなウィキペディア から:

Stdlib.hおよびstddef.hヘッダーファイルは、オブジェクトのサイズを表すために使用されるsize_tと呼ばれるデータ型を定義します。サイズを取るライブラリ関数は、サイズがsize_tであると想定し、sizeof演算子はsize_tに評価されます。

Size_tの実際のタイプはプラットフォームに依存します。よくある間違いは、size_tがunsigned intと同じであると仮定することです。これにより、特に64ビットアーキテクチャが普及するにつれて、プログラミングエラーが発生する可能性があります。

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

142
Joao da Silva

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

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

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

30
Axelle Ziegler

これは、size_tがint(おそらく構造体)以外のものになる可能性があるためです。アイデアは、基本的なタイプから仕事を切り離すことです。

8
graham.reeds

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

歴史的に、アドレスがintのネイティブサイズよりも広いまたは短い他のプラットフォームがいくつかありました。実際、70年代から80年代初期には、これは一般的でした。人気のあるすべての8ビットマイコンには、8ビットのレジスタと16ビットのアドレスがありました。レジスタよりも広いアドレスがありました。 MS-DOS用のBorland Turbo Cについて、16ビットCPU上の32ビットに20ビットアドレスが格納されている(しかし、これは80386の32ビット命令セットをサポートできます)という質問が時々あります。 Motorola 68000には、32ビットのレジスタとアドレスを備えた16ビットのALUがありました。 15ビット、24ビット、または31ビットのアドレスを持つIBMメインフレームがありました。また、組み込みシステムでは異なるALUおよびアドレスバスサイズが表示されます。

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

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

ただし、回避策は、すべてのアドレスとオフセットをINT_MAXおよび0またはINT_MINのいずれかに対して境界検査し、あなたが何かを見逃した場合。とにかく、常に、常にCでオーバーフローの配列アクセスをチェックする必要があります。

7
Davislor

SIZE_Tの定義は、次の場所にあります: https://msdn.Microsoft.com/en-us/library/cc441980.aspx および https://msdn.Microsoft .com/en-us/library/cc230394.aspx

必要な情報をここに貼り付けます:

SIZE_Tは、ポインターがポイントできる最大バイト数を表すULONG_PTRです。

このタイプは次のように宣言されます。

typedef ULONG_PTR SIZE_T;

ULONG_PTRは、ポインターの精度に使用される符号なしlong型です。ポインター演算を実行するためにポインターをlong型にキャストするときに使用されます。

このタイプは次のように宣言されます。

typedef unsigned __int3264 ULONG_PTR;
0
sundar