Answers:
来自友好的维基百科:
stdlib.h和stddef.h头文件定义了一个称为size_t的数据类型,该数据类型用于表示对象的大小。占用大小的库函数希望它们的大小为size_t,而sizeof运算符的计算结果为size_t。
size_t的实际类型取决于平台。一个常见的错误是假定size_t与unsigned int相同,这可能导致编程错误,尤其是在64位体系结构变得更加流行时。
另外,检查为什么size_t很重要
/usr/include/stdlib.h
从中获取定义,/usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.h
并且默认情况下为默认值,long unsigned int
除非其他头文件另有说明。
size_t是用于表示尺寸的类型(顾名思义)。其平台(甚至可能实现)依赖于此,并且仅应用于此目的。显然,代表大小,size_t是无符号的。许多stdlib函数(包括malloc,sizeof和各种字符串操作函数)都将size_t用作数据类型。
默认情况下,一个int是带符号的,尽管它的大小也取决于平台,但在大多数现代机器上它将是固定的32位(尽管size_t在64位体系结构上为64位,但int在那些体系结构上仍保持32位长)。
总结一下:使用size_t表示对象的大小,在其他情况下使用int(或long)表示。
该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
,也有可能得到负数。如果int
或unsigned int
较宽,则程序将正确运行,但会浪费内存。
如果要携带,通常应为此使用正确的类型。很多人会建议您使用带符号的数学而不是无符号的数学(以避免诸如的讨厌,细微的错误1U < -3
)。为此,标准库将ptrdiff_t
in 定义<stddef.h>
为从另一个指针减去结果的有符号类型。
这就是说,一个解决办法可能是边界检查所有的地址和偏移对INT_MAX
,要么0
或INT_MIN
酌情并开启有关比较签订的编译器警告和无符号数量万一你错过任何。无论如何,您应该始终始终检查数组访问是否存在C溢出。
这是因为size_t可以是int以外的任何其他内容(可能是struct)。其思想是将其工作与基础类型分离。
size_t
指定为无符号整数类型。C11§6.5.3.45“两个运算符(sizeof
_Alignof
)的结果值都是实现定义的,其类型(无符号整数类型)为size_t
”。
可在以下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;
SIZE_T
不是size_t
,OP询问了什么。
SIZE_T
与完全不同size_t
。您不能声明类型为的变量SIZE_T
。