下面的代码在Windows中执行时返回一个地址,虽然我希望它返回NULL .
int main() { char *ptr = NULL; ptr = malloc(0); printf("malloc returned = %u\n", ptr); }
什么可能促使malloc的这种实现?它背后有什么理由吗?
因为,这是一个0字节的内存,我没有尝试写任何数据 . 但是,这个记忆可以用于任何东西吗?
这只是您要求的最小尺寸 . 由于Win32堆中没有零长度块,您可以:
void *p = malloc(0); // ... do some stuff in between... realloc(p, n);
这应该主要导致重用堆的块(如果你很幸运,新的大小很小) . 一个小的机会主义优化(或减慢,取决于上下文和血液咖啡水平) .
这是一个简化的例子 . 实际情况可能是一个在创建缓冲区时分配缓冲区的类,也允许增长缓冲区 . 如果输入很难控制,你可以让它做零大小的缓冲区分配 .
要回答你问题的第二部分,内存不能用于任何事情,因为“它的可访问部分”是从返回的地址开始的0字节 .
IIRC保证,如果实现确实返回非空,那么它将是与任何其他当前分配的内存块不同的地址 . 因此理论上你可以使用地址作为临时唯一ID(指针类型),尽管很明显还有很多其他方法可以获得唯一ID . 即使你打算使用它, malloc(1) 也可以和_693117一样工作,并且更加便携 .
malloc(1)
这是在comp.lang.c中回答的问题:http://c-faq.com/ansi/malloc0.html
ANSI / ISO标准说它可以做任何一种;行为是实现定义的(见问题11.33) . 可移植代码必须注意不要调用malloc(0),或者为空返回的可能性做好准备 .
标准说它可以做到
http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
这不是没用的 . 从malloc返回的块应该是唯一的 . 因此,malloc返回的每个块都携带块内的数据和它的唯一标识符,即它的地址 . 如果后一个属性很重要,并且它不包含数据这一事实不是问题,那么它很有用 .
但是,如上所述,它是编写非可移植代码的好方法 . 然而,这与非法代码不同,它对于支持它的实现是完全有效的(显然是windows) .
5 回答
这只是您要求的最小尺寸 . 由于Win32堆中没有零长度块,您可以:
这应该主要导致重用堆的块(如果你很幸运,新的大小很小) . 一个小的机会主义优化(或减慢,取决于上下文和血液咖啡水平) .
这是一个简化的例子 . 实际情况可能是一个在创建缓冲区时分配缓冲区的类,也允许增长缓冲区 . 如果输入很难控制,你可以让它做零大小的缓冲区分配 .
要回答你问题的第二部分,内存不能用于任何事情,因为“它的可访问部分”是从返回的地址开始的0字节 .
IIRC保证,如果实现确实返回非空,那么它将是与任何其他当前分配的内存块不同的地址 . 因此理论上你可以使用地址作为临时唯一ID(指针类型),尽管很明显还有很多其他方法可以获得唯一ID . 即使你打算使用它,
malloc(1)
也可以和_693117一样工作,并且更加便携 .这是在comp.lang.c中回答的问题:http://c-faq.com/ansi/malloc0.html
标准说它可以做到
http://pubs.opengroup.org/onlinepubs/009695399/functions/malloc.html
这不是没用的 . 从malloc返回的块应该是唯一的 . 因此,malloc返回的每个块都携带块内的数据和它的唯一标识符,即它的地址 . 如果后一个属性很重要,并且它不包含数据这一事实不是问题,那么它很有用 .
但是,如上所述,它是编写非可移植代码的好方法 . 然而,这与非法代码不同,它对于支持它的实现是完全有效的(显然是windows) .