【问题标题】:what happens when we call Malloc with negative parameter?当我们用负参数调用 Malloc 时会发生什么?
【发布时间】:2013-07-29 08:17:20
【问题描述】:

7.22.3.4 malloc 函数 malloc 函数为一个对象分配空间,该对象的大小由 size 指定,其值为 不确定。

原型:void *malloc(size_t size);

我尝试将负值作为参数传递:malloc(negative) 返回NULL

是因为 [size_t] 负数转换为无符号 [某个大值] 并且无法分配所需的空间还是函数检查参数并返回 NULL

如果它被转换为大正数,那么在调用malloc(INT_MIN+2) 时它仍然返回NULL,但malloc(0) 分配给指针并且*p = somevalue 有效。这个呢?

是否定义了实现?

阅读此链接:malloc(0)

【问题讨论】:

  • size_t 是无符号类型 ssize_t 将被签名。

标签: c malloc


【解决方案1】:

由于 malloc 的参数是 size_t 类型,它是无符号的,但您传递的是一个有符号整数,整数值将转换为 size_t这方面的规则在草案 C99 标准部分 6.3.1.3 有符号和无符号整数 中进行了介绍,它属于 Conversions,它说:

否则,如果新类型是无符号的,则通过重复添加或转换值 比新类型可以表示的最大值多减一 直到值在新类型的范围内。49)

让我们看一个例子来说明这意味着什么,如果你传入-1,那么 max size_t value + 1 将被添加:

-1 + MAX_SIZE_T + 1

导致:

 MAX_SIZE_T

对于-5,您最终会得到:

MAX_SIZE_T - 4

这意味着对于小的负值,生成的 size_t 值将是一个非常大的正数。

那么在这些情况下,为什么您会收到 NULLmalloc 回复?如果我们回到草案标准部分7.20.3 内存管理功能,它会说:

如果无法分配空间,则为空指针 返回

您的请求过大,无法分配空间。

【讨论】:

    【解决方案2】:

    即使您将负值传递给 mallocsize_t 值也始终为正值。负值被转换为size_t 类型的无符号值,这会导致一个巨大的正值。

    例子:

    char *p = malloc(-2);
    

    相当于:

    char *p = malloc(SIZE_MAX - 1);  // SIZE_MAX is the maximum
                                     // size_t value 
    

    【讨论】:

    • 大小如何确定?即使我有可能的内存大小?让我们说 8 GB 内存? [或内存仅限于程序]
    • @Dineshkumar 如何将大小转换为无符号整数取决于 IIRC 的实现。然而,现在大多数架构都使用二进制补码和相应的转换。通过编写一个与 malloc 具有相同参数类型的函数进行测试并在其中打印它。在 Linux 上,启用内存过量使用后,malloc 基本上永远不会失败,无论您向它传递什么(可能仅在地址空间耗尽时)。但是,尝试写入比可用内存更多的(虚拟)内存将导致 SIGSEGV。我不确定 Windows,但可能类似。
    • @spbnick this 实际上不是实现定义的,由 (c99, 6.3.1.3p2) "统治,否则如果新类型是无符号的,则通过重复加减来转换值比新类型可以表示的最大值大一,直到值在新类型的范围内”
    • 当我通过 malloc(INT_MIN+offset) 时,它应该会产生一个小的正值,但它仍然会导致 NULL?
    • @Dineshkumar:假设intsize_t 都是32 位。如果INT_MIN == -2147483648offset == 100,则INT_MIN + offset == -2147483548,当转换为32 位size_t 时产生+2147483748
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    • 2016-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多