标题实际上有点误导,但我想保持简短。我已经阅读了为什么我应该使用 size_t 并且我经常发现这样的陈述:
size_t
保证能够表达任何对象的最大尺寸,包括任何数组
我真的不明白那是什么意思。您可以一次分配多少内存并且 size_t 保证足够大以计算该内存块中的每个字节,是否有某种上限?
追问:
什么决定了可以分配多少内存?
标题实际上有点误导,但我想保持简短。我已经阅读了为什么我应该使用 size_t 并且我经常发现这样的陈述:
size_t
保证能够表达任何对象的最大尺寸,包括任何数组
我真的不明白那是什么意思。您可以一次分配多少内存并且 size_t 保证足够大以计算该内存块中的每个字节,是否有某种上限?
追问:
什么决定了可以分配多少内存?
假设您的编译器/平台可以拥有的最大对象是 4 GB。size_t
然后是32位。现在假设您在能够支持大小为 2^43 - 1 的对象的 64 位平台上重新编译您的程序。size_t
将至少有 43 位长(但通常此时它将是 64 位)。关键是您只需要重新编译程序。您不必将所有int
s 更改为long
(如果int
是 32 位并且long
是 64 位)或从int32_t
to int64_t
。(如果您问自己为什么是 43 位,假设 Windows Server 2008 R2 64 位不支持大小为 2^63 的对象,也不支持大小为 2^62 的对象......它支持8 TB的可寻址空间......所以 43少量!)
许多为 Windows 编写的程序都认为指针与 a DWORD
(32 位无符号整数)一样大。如果不重写大量代码,就无法在 64 位上重新编译这些程序。如果他们使用DWORD_PTR
(一个无符号值保证与包含指针所需的一样大),他们就不会遇到这个问题。
“size_t
点”是类似的。但不一样!
size_t
不保证能够包含指针!!
(DWORD_PTR
Microsoft Windows 是)
一般来说,这是非法的:
void *p = ...
size_t p2 = (size_t)p;
例如,在旧的 DOS“平台”上,对象的最大大小为 64k,因此size_t
需要为 16 位,但远指针需要至少为 20 位,因为 8086 的内存空间为 1 mb(在远指针的末尾是 16 + 16 位,因为 8086 的内存是分段的)
基本上这意味着size_t
, 保证足够大以索引任何数组并获得任何数据类型的大小。
它比使用 just 更可取int
,因为int
和其他整数类型的大小可以小于可以索引的大小。例如int
,通常是 32 位长,这不足以在 64 位机器上索引大型数组。(在将程序移植到 64 位时,这实际上是一个非常常见的问题。)
这正是原因。给定编程语言中任何对象的最大大小由操作系统、CPU 体系结构和使用的编译器/链接器共同决定。
size_t 被定义为足够大以容纳最大可能对象的大小值。
这通常意味着 size_t 的类型定义为与可用的最大 int 类型相同。所以在 32 位环境中它通常是 4 个字节,而在 64 位系统中是 8 个字节。
size_t
是为您正在编译的平台定义的。因此,它可以代表该平台的最大值。
size_t 是 sizeof 运算符的返回值(参见 7.17 c99),因此它必须描述系统可以表示的最大可能对象。