C 中 size_t 类型的 malloc 参数的限制是多少?文档说它的上限为 UINT_MAX但我不能超过INT_MAX



我想用分配一个2.9GB的char数组

  database = (char*) malloc((2900 * 1000000 * sizeof(char)));

这会发出整数溢出警告,并且malloc返回NULL。这个malloc参数的类型为size_t,根据文件,其类型为unsigned int

因此,最大值应该是UINT_MAX,至少为2.9GB。但是,如果我试图分配超过MAX_INTmalloc失败。这意味着我的系统上的size_t的类型是int?我该如何检查?我浏览了

/usr/include/stdlib.h 

./lib/gcc/x86_64-redhat-linux/4.1.1/include/stddef.h 

但是找不到CCD_ 10的定义。非常感谢

参数的类型为size_tmalloc需要接受任何可能的size_t类型的值。请注意,"接受"并不意味着需要分配那么多;这意味着malloc不允许由于溢出问题而将你给它的一个很大的数字误解为一个小/负数,从而返回一个太小的缓冲区,并创建一个你的程序无法防御的无法检测的关键漏洞。malloc可能无法分配非常大的对象,原因有很多:

  • 系统没有那么多内存
  • 由于碎片化,没有那么大的连续虚拟地址范围可用
  • 任意极限

在这种情况下,我怀疑你可能看到了第三个任意的限制,尽管我不认为它们是如此武断。有一个很好的理由不允许大于SIZE_MAX/2的分配(以及任何对象的存在):当结果不适合(带符号)类型ptrdiff_t时,在这样大的对象中获取指针之间的差异将导致(极其危险的)整数溢出和未定义行为。因此,在健壮的32位系统上,虽然虚拟地址空间大小为4GB,但任何单个对象的最大大小都将为2GB。

这里有两个问题。

首先,溢出警告:29001000000都是int类型,所以相乘的结果也是int类型。结果不能用32位有符号整数表示,因此会溢出。您需要将一个(或两个)参数强制转换为size_t才能使用无符号算术。

(或者,您可以将sizeof(char)移动为前两个项之一,因为它的类型是size_t,但也可以删除sizeof(char),因为它总是1。)

其次,malloc可以分配的最大大小取决于运行的平台和程序的当前状态。如果没有足够的连续地址空间来满足请求,那么显然malloc将失败。

此外,您运行的平台可能对其可以动态分配的对象大小有上限。您需要查阅您的平台文档,以了解上限是多少。

size_t当然不是int,因为int总是有符号的,而size_t总是无符号的。

malloc可以分配的最大大小取决于运行的平台和程序的当前状态。如果没有足够的连续地址空间来满足请求,malloc显然会失败。

最新更新