Malloc不返回NULL

时间:2016-02-13 10:47:31

标签: c memory malloc out-of-memory

我刚用一个巨大的内存请求测试malloc,但它没有返回NULL。我已经听说过这个但是BSD(我在Mac上)man-page说:

  

返回值
       如果成功,calloc()malloc()realloc()reallocf()valloc()函数将返回指向已分配内存的指针。如果        如果出现错误,则返回NULL指针并将errno设置为ENOMEM

如何正确可靠地检查返回的指针指向请求大小的有效块?

编辑:我刚看到this帖子。对于BSD我也一样吗?

编辑2:代码:

typedef struct {
    uint8_t red;
    uint8_t green;
    uint8_t blue;
} RGB_TYPE;

int main() {
    RGB_TYPE *field = malloc(50000 * 50000 * sizeof(RGB_TYPE));

    if (!field)
        return -1;

    ... write to field (SEG_FAULT) ... 

    return 0;
}

1 个答案:

答案 0 :(得分:4)

问题的原因有点棘手:

50000*50000*sizeof(RGB_TYPE)评估为(size_t)(50000 * 50000) * sizeof(RGB_TYPE)。乘法从左向右关联,因此第一次乘法使用int算术和溢出执行,因为2500000000大于您平台上的INT_MAX

整数溢出调用未定义的行为,您的平台(clang)可能会在这种情况下生成愚蠢的代码。如果指示(clang -Wallclang -Weverything),它可以产生诊断。在任何情况下,您的代码都会崩溃,因为该数组没有预期的大小。

将代码更改为

RGB_TYPE *field = malloc(sizeof(RGB_TYPE) * 50000 * 50000);

此外,您的计算机上可能会分配7.5 GB的内存。这将取决于系统配置,但即使你只有8GB的RAM,OS / X也会允许这样做是不现实的。

编辑:在我的Mac上,您的代码确实不会产生clang -Weverything的警告,这是一个真正的麻烦,并尝试分配18446744068324649728个字节。我从malloc获得了运行时警告:

malloc-test(53877,0x7fff79dbe000) malloc: 
   *** mach_vm_map(size=18446744068324651008) failed (error code=3)
   *** error: can't allocate region
   *** set a breakpoint in malloc_error_break to debug

malloc返回NULL。您可能拥有不同版本的工具和运行时库。