我使用malloc()
分配了一块内存,然后用realloc()
修改了它。
在代码的某个点上,我想要清空它,也就是说,将其内存大小设置为0。直觉上,这可以通过realloc(pointer, 0)
来完成。但我在这里阅读到,这是由具体实现决定的,不应该使用。
那么我应该使用free()
来释放内存,然后再使用malloc()
重新分配内存吗?
这要看你的意思: 如果你想“清空已使用的内存”,但仍然需要访问该内存,则可以使用 memset(pointer, 0, mem_size);
,将该内存重新初始化为零。
如果不再需要该内存,则只需调用free(pointer);
,这将释放内存,以便别处可以使用。
在某些系统上使用realloc(pointer, 0)
可能像free
一样工作,但这并不是标准行为。C99或C11标准未指定realloc(ptr, 0)
等效于free(ptr)
。
realloc(pointer, 0)
不等同于free(pointer)
。标准(C99,§7.22.3.5):
realloc函数 概述 1#include <stdlib.h> void *realloc(void *ptr, size_t size);
描述 2 realloc函数释放ptr指向的旧对象,并返回一个指针,该指针指向大小由size指定的新对象。新对象的内容应与先前解除分配之前的旧对象相同,最多到新旧大小中较小的那个为止。新对象中超出旧对象大小的任何字节都具有不确定的值。 3 如果ptr是空指针,则realloc函数根据指定的大小像malloc函数一样工作。否则,如果ptr与先前由内存管理函数返回的指针不匹配,或者该空间已被调用free或realloc函数释放,则其行为未定义。如果无法为新对象分配内存,则不会解除分配旧对象,并且其值保持不变。 返回 4 realloc函数返回一个指向新对象的指针(可能具有与旧对象相同的值),如果无法分配新对象,则返回空指针。
正如您所看到的,它没有为realloc调用指定大小为0的特殊情况。相反,它只说明在分配内存失败时返回NULL指针,在所有其他情况下返回指针。然后,一个指向0字节的指针将是一个可行的选项。
引用相关问题:
更直观地说,realloc在概念上等同于在另一个指针上malloc + memcpy + free,而mallocing一个0字节的内存块会返回NULL或唯一指针,不用于存储任何东西(你要求0字节),但仍需要free。因此,不要像这样使用realloc,它可能在一些实现(即Linux)上工作,但不能保证。
正如链接问题中的另一个答案所述,《C11标准》明确定义了realloc(ptr, 0)
的行为为实现定义:
如果请求的空间大小为零,则行为是实现定义的:要么返回空指针,要么行为就好像大小为某个非零值,除了返回的指针不应用于访问对象
realloc(pointer, 1)
仍然可以保留指针,这将释放接近所有的内存,而且你仍然可以使用指针。 - Elias Van Ootegemrealloc(pointer, sizeof *pointer)
... 我不明白这怎么会导致未定义的行为... - Elias Van Ootegemrealloc(pointer,0)
释放它是强制性的。我认为在较新的C和POSIX标准中不释放它是强制性的。 - 12431234123412341234123手册页面说:
如果ptr为
NULL
,则对于所有的size
值,调用等效于malloc(size)
;如果size
等于零且ptr
不是NULL
,则调用等效于free(ptr)
。
传统上,您可以使用realloc(ptr, 0);
作为free(ptr);
的同义词,就像您可以使用realloc(NULL, size);
作为malloc(size);
的同义词一样。不过我不建议这样做,因为有点令人困惑,不符合人们的预期使用方式。
然而,现代C语言中定义已经改变:现在realloc(ptr, 0);
将释放旧内存,但接下来会做什么并没有明确定义:这是实现相关的。
所以:不要这样做:使用free()
释放内存,并让realloc()
仅用于将大小更改为非零值。
realloc()
的方式似乎已经过时了。请看一下我的答案。 - alkrealloc(ptr, 0)
将释放旧内存,但下一步做什么并不明确:这是实现定义的。如果realloc
返回NULL
,则表示分配失败,在分配失败时,旧内存不会被释放。 - user743382使用free(pointer); pointer = 0
代替realloc(pointer, 0)
。
void* realloc (void* ptr, size_t size);