5

我想分配一个 2.9GB 的字符数组

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

这会给出一个整数溢出警告和malloc返回NULL。该 malloc参数是 type size_t,根据文档是 type unsigned int

所以最大值应该UINT_MAX是至少2.9GB。MAX_INT但是,如果我尝试分配多于malloc失败。这是否意味着 size_t在我的系统上是 int 类型?我该如何检查?我看过

/usr/include/stdlib.h 

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

但找不到 的定义size_t。非常感谢

4

3 回答 3

10

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

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

在这种情况下,我怀疑您可能会看到第三个任意限制,尽管我不会认为它们如此任意。有一个很好的理由来禁止大于 的分配(以及任何对象的存在)SIZE_MAX/2:当结果不适合 (signed ) 类型ptrdiff_t。因此,在一个健壮的 32 位系统上,虽然虚拟地址空间大小为 4GB,但任何单个对象的最大大小为 2GB。

于 2012-03-02T17:56:16.060 回答
9

这里有两个问题。

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

(或者,您可以将 thesizeof(char)移到前两个术语之一,因为它的类型是size_t,尽管您也可以删除 the ,sizeof(char)因为它始终是1。)

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

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

size_t肯定不是int,因为int总是有符号且size_t总是无符号的。

于 2012-03-02T17:52:40.393 回答
1

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

于 2017-09-28T10:51:36.327 回答