Joa*_*lva 144
来自友好的维基百科:
stdlib.h和stddef.h头文件定义了一个名为size_t的数据类型,用于表示对象的大小.采用大小的库函数期望它们的类型为size_t,而sizeof运算符的计算结果为size_t.
size_t的实际类型取决于平台; 一个常见的错误是假设size_t与unsigned int相同,这可能导致编程错误,特别是当64位架构变得更加普遍时.
另外,检查为什么size_t很重要
Axe*_*ler 32
size_t是用于表示大小的类型(顾名思义).它的平台(甚至可能的实现)依赖,并且只应用于此目的.显然,表示大小,size_t是无符号的.许多stdlib函数(包括malloc,sizeof和各种字符串操作函数)使用size_t作为数据类型.
默认情况下,int是有符号签名的,即使它的大小也依赖于平台,它在大多数现代机器上都是固定的32位(虽然size_t在64位架构上是64位,但在这些架构上int仍然是32位长).
总结一下:使用size_t表示对象的大小,在其他情况下使用int(或long).
这是因为size_t可以是除int之外的任何东西(可能是结构).这个想法是它将它的工作与底层类型分离开来.
该size_t类型定义为sizeof运算符的无符号整数类型.在现实世界中,您经常会看到int定义为32位(为了向后兼容),但size_t在64位平台上定义为64位(因此您可以声明大小超过4 GiB的数组和结构).如果a long int也是64位,则称为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的问题,其巨大的内存模式在16位CPU上以32位存储了20位地址(但可以支持80386的32位指令集); Motorola 68000有一个带有32位寄存器和地址的16位ALU; IBM主机有15位,24位或31位地址.您还会在嵌入式系统中看到不同的ALU和地址总线大小.
任何时间int都小于size_t,并且您尝试将非常大的文件或对象的大小或偏移存储在unsigned int其中,它可能会溢出并导致错误.有了int,也有可能得到一个负数.如果a int或unsigned int更宽,程序将正确运行但浪费内存.
如果您想要可移植性,通常应该使用正确的类型.很多人会建议你使用带符号的数学而不是unsigned(以避免令人讨厌的,微妙的错误1U < -3).为了这个目的,标准库定义ptrdiff_t中<stddef.h>作为有符号的类型减去另一个的指针的结果.
这就是说,一个解决办法可能是边界检查所有的地址和偏移对INT_MAX,要么0或INT_MIN酌情并开启有关比较签订的编译器警告和无符号数量万一你错过任何.无论如何,您应始终始终检查数组访问是否存在溢出.