C ++中的size_t和int有什么区别?


Answers:


152

来自友好的维基百科

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

1
我确认将size_t设置为整数是危险的。这可能是题外话,但是当它在Linux内核中发生数千次时,如何单独编写补丁来解决这种错误呢?
user2284570

35

size_t是用于表示尺寸的类型(顾名思义)。其平台(甚至可能实现)依赖于此,并且仅应用于此目的。显然,代表大小,size_t是无符号的。许多stdlib函数(包括malloc,sizeof和各种字符串操作函数)都将size_t用作数据类型。

默认情况下,一个int是带符号的,尽管它的大小也取决于平台,但在大多数现代机器上它将是固定的32位(尽管size_t在64位体系结构上为64位,但int在那些体系结构上仍保持32位长)。

总结一下:使用size_t表示对象的大小,在其他情况下使用int(或long)表示。


11

size_t类型定义为sizeof运算符的无符号整数类型。在现实世界中,您经常会在64位平台上看到int定义为32位(为了向后兼容),但size_t定义为64位(因此可以声明大小超过4 GiB的数组和结构)。如果a long int也是64位,则称为LP64约定;否则,这称为LP64约定。如果long int是32位,但long long int指针是64位,则为LLP64。您可能还会得到相反的结果,该程序使用64位指令来提高速度,但是使用32位指针来节省内存。同样,int已签名和size_t未签名。

从历史上看,还有许多其他平台的地址比本地大小宽或短int。实际上,在70年代和80年代初,这种情况非常普遍:所有流行的8位微型计算机都具有8位寄存器和16位地址,而16位和32位之间的转换也产生了许多机器,地址的范围超出了其寄存器的范围。我偶尔仍然在这里看到有关MS-DOS的Borland Turbo C的问题,它的巨大内存模式在20位地址中以16位CPU的32位存储(但可以支持80386的32位指令集)。摩托罗拉68000具有带32位寄存器和地址的16位ALU;有具有15位,24位或31位地址的IBM大型机。您还会在嵌入式系统中看到不同的ALU和地址总线大小。

任何时间int都小于size_t,并且您尝试将非常大的文件或对象的大小或偏移量存储在中unsigned int,则可能会溢出并引起错误。使用int,也有可能得到负数。如果intunsigned int较宽,则程序将正确运行,但会浪费内存。

如果要携带,通常应为此使用正确的类型。很多人会建议您使用带符号的数学而不是无符号的数学(以避免诸如的讨厌,细微的错误1U < -3)。为此,标准库将ptrdiff_tin 定义<stddef.h>为从另一个指针减去结果的有符号类型。

这就是说,一个解决办法可能是边界检查所有的地址和偏移对INT_MAX,要么0INT_MIN酌情并开启有关比较签订的编译器警告和无符号数量万一你错过任何。无论如何,您应该始终始终检查数组访问是否存在C溢出。


8

这是因为size_t可以是int以外的任何其他内容(可能是struct)。其思想是将其工作与基础类型分离。


8
我认为size_t实际上可以保证是无符号整数的别名,因此它不能是结构。不过,我现在没有参考资料可以方便地对此进行备份。
放松

9
@unwind:C99:TC3,7.17§2–
Christoph

1
@danio为什么会这样?您能解释一下吗?
鲁佩尔的秃鹰

2
如果我是你,我不会链接到cplusplus!如果您不能引用章节,经文,段落和行,那么这只是传闻!:-)
graham.reeds 2013年

1
size_t指定为无符号整数类型。C11§6.5.3.45“两个运算符(sizeof _Alignof)的结果值都是实现定义的,其类型(无符号整数类型)为size_t”。
chux-恢复莫妮卡2015年

-1

可在以下SIZE_T位置找到的定义:https//msdn.microsoft.com/zh-cn/library/cc441980.aspx https://msdn.microsoft.com/en-us/library/cc230394.aspx

在此处粘贴所需的信息:

SIZE_T 是一个 ULONG_PTR代表指针可以指向的最大字节数。

此类型声明如下:

typedef ULONG_PTR SIZE_T;

一个 ULONG_PTR是用于指针精度的无符号长型。在将指针强制转换为long类型以执行指针算术时使用。

此类型声明如下:

typedef unsigned __int3264 ULONG_PTR;

2
SIZE_T不是size_t,OP询问了什么。
ikegami

2
那是Microsoft的扩展,不是标准语言的一部分。
戴维斯洛

SIZE_T与完全不同size_t。您不能声明类型为的变量SIZE_T
calocedrus
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.