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


回答:


153

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

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

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

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


76
それで、size_tとは何ですか?
NDEthos

8
@NDEthos場合によります!ここで、Linux /usr/include/stdlib.hは定義/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.hをそこから取得し、long unsigned int他のヘッダーファイルで特に指定されていない限り、デフォルトでデフォルトになります。
David Tonhofer 2016年

1
size_tからint tuncationへのアクセスは危険であることを確認しました。これは主題外かもしれませんが、Linuxカーネルで何千回も発生するような種類のミスを修正するパッチを単独で作成する方法は?
user2284570 2016

36

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

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

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


12

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

歴史的に、アドレスがのネイティブサイズより広いまたは短い他の多くのプラットフォームがありましたint。実際、70年代から80年代初頭にかけて、これは一般的でした。人気のあるすべての8ビットマイクロコンピューターには8ビットレジスターと16ビットアドレスがあり、16ビットと32ビット間の移行によって、それらのレジスターより広いアドレスを持っていた。MS-DOS用のBorland Turbo Cに関する質問が時々見られます。その巨大メモリモードでは、16ビットCPUの32ビットに格納された20ビットアドレスがありました(ただし、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でのオーバーフローについて配列アクセスをチェックする必要があります。


8

これは、size_tがint(おそらく構造体)以外の値になる可能性があるためです。考えは、それはその仕事を基礎となるタイプから切り離すということです。


8
size_tは実際には符号なし整数のエイリアスになることが保証されていると思うので、構造体にすることはできません。ただ、現時点でこれをバックアップするのに便利なリファレンスはありません。
アンワインド

9
@unwind:C99:TC3、7.17§2
クリストフ・

1
@danioなぜそうなのですか?説明できますか?
ルッペルのハゲタカ

2
私があなただったら、cplusplusにリンクしません!チャプター、バース、パラグラフ、ラインを引用できない場合、それはすべてただの噂です!:-)
graham.reeds 2013

1
size_t符号なし整数型として指定されてます。C11§6.5.3.45「両方の演算子(sizeof _Alignof)の結果の値は実装定義であり、その型(符号なし整数型)はsize_t、」です。
chux-モニカを2015年

-1

の定義は、httpsSIZE_T//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;

A ULONG_PTRは、ポインター精度に使用されるunsigned long型です。これは、ポインターをlong型にキャストしてポインター演算を実行するときに使用されます。

この型は次のように宣言されます。

typedef unsigned __int3264 ULONG_PTR;

2
SIZE_Tsize_t、OPが尋ねたものではありません。
池上

2
これはMicrosoftの拡張機能であり、標準言語の一部ではありません。
Davislor 2018年

SIZE_Tとはまったく異なりsize_tます。型の変数を宣言することはできませんSIZE_T
calocedrus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.