为什么malloc(0)在Windows中返回非空地址?

时间:2012-03-15 15:35:48

标签: c memory-management malloc

以下代码在Windows中执行时会返回一个地址,但我希望它返回NULL。

int main()
{
   char *ptr = NULL;
   ptr = malloc(0);
   printf("malloc returned = %u\n", ptr);

}

什么可能促使malloc的这种实现?它背后有什么理由吗?

因为,这是一个0字节的内存,我没有尝试写任何数据。但是,这个记忆可以用于任何事情吗?

5 个答案:

答案 0 :(得分:9)

这只是您要求的最小尺寸。由于Win32堆中没有零长度块,您可以:

void *p = malloc(0);
// ... do some stuff in between...
realloc(p, n);

哪个应该主要导致重用堆的块(如果你很幸运,新的大小很小)。一个小的机会主义优化(或减慢,取决于背景和血液咖啡水平)。

这是一个简化的例子。实际情况可能是一个在创建缓冲区时分配缓冲区的类,也允许增长缓冲区。如果输入很难控制,你可以让它进行零大小的缓冲区分配。

答案 1 :(得分:8)

要回答你的问题的第二部分,内存不能用于任何事情,因为“它的可访问部分”是从返回的地址开始的0字节。

IIRC可以保证,如果实现确实返回非空,那么它将是来自任何其他当前分配的内存块的不同的地址。因此理论上你可以使用地址作为临时唯一ID(指针类型),尽管显然还有很多其他方法可以获得唯一ID。即使你打算使用它,malloc(1)也可以像malloc(0)一样工作,并且更加便携。

答案 2 :(得分:7)

在comp.lang.c常见问题中回答:http://c-faq.com/ansi/malloc0.html

  

ANSI / ISO标准说它可以做任何一种;行为是实现定义的(见问题11.33)。可移植代码必须注意不要调用malloc(0),或者为空返回的可能性做好准备。

答案 3 :(得分:3)

答案 4 :(得分:0)

这不是没用的。从malloc返回的块应该是唯一的。因此,malloc返回的每个块都携带块内的数据和它的唯一标识符,即它的地址。如果后一个属性很重要,并且它不包含数据这一事实不是问题,那么它很有用。

然而,正如所提到的,它是编写非可移植代码的好方法。然而,这与非法代码不同,它对于支持它的实现是完全有效的(显然是windows)。