pnk*_*lix 43 c malloc free memory-management
我一直在阅读有关malloc当您请求零大小的块时的行为的讨论.
我理解malloc(0)是实现定义的行为,它应该返回一个空指针,或者我仍然不应该访问的非空指针.(这是有道理的,因为不能保证它指向任何可用的内存.)
但是,如果获得这样一个不可访问的非空指针,我是否允许以free通常的方式传递给它?或者这是非法的,因为我得到的指针malloc(0)可能不指向实际分配的内存块?
具体而言,以下代码是否具有明确定义的行为:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* x = (int*) malloc(0);
if (x == NULL) {
printf("Got NULL\n");
return 0;
} else {
printf("Got nonnull %p\n", x);
}
free(x); // is calling `free` here okay?
}
Run Code Online (Sandbox Code Playgroud)
apr*_*ori 41
C99标准(实际上是WG14/N1124.委员会草案 - 2005年5月6日.ISO/IEC 9899:TC2)说malloc():
返回的指针指向分配空间的开始(最低字节地址).如果无法分配空间,则返回空指针.如果请求的空间大小为零,则行为是实现定义的:返回空指针,或者行为就像大小是非零值一样,除了返回的指针不应该用于访问对象
和关于free():
否则,如果参数与之前由calloc,malloc或realloc函数返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则行为未定义.
IEEE Std 1003.1-2008(POSIX),2016版说free():
free()函数将导致ptr指向的空间被释放; 也就是说,可供进一步分配.如果ptr是空指针,则不会发生任何操作.否则,如果参数与之前由POSIX.1-2008中的函数返回的指针不匹配,该函数像malloc()一样分配内存,或者如果通过调用free()或realloc()释放空间,行为未定义.
所以,无论*alloc()回报如何,你都可以转而去free().
至于目前的实施malloc():
FreeBSD使用贡献的jemalloc
void *
je_malloc(size_t size)
{
void *ret;
size_t usize JEMALLOC_CC_SILENCE_INIT(0);
if (size == 0)
size = 1;
[...]
Run Code Online (Sandbox Code Playgroud)
Apple的libmalloc确实如此
void *
szone_memalign(szone_t *szone, size_t alignment, size_t size)
{
if (size == 0) {
size = 1; // Ensures we'll return an aligned free()-able pointer
[...]
Run Code Online (Sandbox Code Playgroud)
GLIBC也改变了要求的大小; 它正在使用对此宏的调用,并将请求的大小(以字节为单位)作为参数,以将大小与特定边界对齐,或者只是最小分配大小:
#define request2size(req) \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
Run Code Online (Sandbox Code Playgroud)
Mal*_*ean 24
是的,实际上你必须这样做以避免可能的内存泄漏.
malloc系统通常在指针之前的空间中返回隐藏的控制块,其具有诸如分配大小的信息.如果分配大小为零,则此块仍然存在并占用内存,如果malloc返回非null.