释放分配的内存:realloc() 与 free()
Posted
技术标签:
【中文标题】释放分配的内存:realloc() 与 free()【英文标题】:Freeing allocated memory: realloc() vs. free() 【发布时间】:2014-03-07 12:44:19 【问题描述】:所以我用malloc()
分配了一块内存,后来用realloc()
进行了更改。
在我的代码中的某个时刻,我想清空它,我的意思是本质上给它的内存为 0。这可以直观地使用 realloc(pointer,0)
完成。我在这里读到这是实现定义的,不应使用。
我应该改用free()
,然后再使用malloc()
吗?
【问题讨论】:
“清空”是什么意思? 【参考方案1】:这取决于您的意思:如果您想清空已使用的内存,但仍然可以访问该内存,那么您使用memset(pointer, 0, mem_size);
,将所述内存重新初始化为零.
如果您不再需要该内存,则只需调用free(pointer);
,这将释放内存,以便在其他地方使用。
在您的系统上使用realloc(pointer, 0)
可能与free
一样工作,但这是不是标准行为。 realloc(ptr, 0)
未被 C99 或 C11 标准指定为等同于 free(ptr)
。
realloc(pointer, 0)
不等同于 free(pointer)
。
标准(C99,§7.22.3.5):
重新分配函数 概要 1 #include如您所见,它没有为大小为 0 的 realloc 调用指定特殊情况。相反,它仅声明在分配内存失败时返回 NULL 指针,在所有其他情况下返回指针。指向 0 字节的指针将是一个可行的选择。
引用a related question:
更直观地说,realloc 在“概念上等价于”另一个指针上的 malloc+memcpy+free,并且 malloc 处理 0 字节内存块返回 NULL 或唯一指针,不用于存储任何内容(您要求 0 个字节),但仍需释放。所以,不,不要像那样使用 realloc,它可能适用于某些实现(即 Linux),但肯定不能保证。
作为该链接问题的另一个答案,realloc(ptr, 0)
的行为根据当前 C11 标准明确定义为实现定义:
如果请求的空间大小为零,则行为是实现定义的:要么返回空指针,要么行为就好像大小是某个非零值,但返回的指针不应用于访问一个对象
【讨论】:
thx 这就是我想要的,我希望以后能够再次重新分配 @user3021085:您应该尽可能多地释放内存,同时仍然可以确定使用realloc(pointer, 1)
保留指针,这样可以释放几乎所有内存,而且您仍然可以准备好指针
是的,但我检查了一些信息。如果我分配给 1,我可能会得到未定义的行为
@user3021085:然后只需使用realloc(pointer, sizeof *pointer)
...我看不出这会如何导致未定义的行为...
C89/C90 标准中就是这种情况。用realloc(pointer,0)
释放它在当时是强制性的。我认为在较新的 C 和 POSIX 标准中不释放它是强制性的。【参考方案2】:
使用free()
释放、释放动态分配的内存。
虽然之前的文档指出realloc(p, 0)
等同于free(p)
,但最新的POSIX documentation 明确指出情况并非如此:
以前的版本明确允许调用 realloc (p, 0) 来释放 p 指向的空间并返回一个空指针。虽然可以将此行为解释为该版本标准允许,但 C 语言委员会已表示该解释是不正确的。
还有更多:
应用程序应该假设如果 realloc() 返回一个空指针,p 指向的空间还没有被释放。
【讨论】:
【参考方案3】:我认为您的意思不是“空”;这意味着“将其设置为我认为为空的某个特定值”(通常所有位都为零)。您的意思是免费或取消分配。
The manual page 说:
如果ptr是
NULL
,那么对于size
的所有值,调用等价于malloc(size)
;如果size
等于0,并且ptr
不是NULL
,则调用等效于free(ptr)
。
传统上,您可以将realloc(ptr, 0);
用作free(ptr);
的同义词,就像您可以将realloc(NULL, size);
用作malloc(size);
的同义词一样。不过我不推荐它,它有点令人困惑,而且不像人们期望的那样使用它。
然而,如今在现代 C 中,定义发生了变化:现在 realloc(ptr, 0);
将释放旧内存,但并没有明确定义接下来要做什么:它是由实现定义的。
所以:不要这样做:使用free()
来释放内存,并让realloc()
用于 将大小更改为非零值。
【讨论】:
这种使用realloc()
的方式似乎已经过时了。请看我的回答。
@alk 是的,它似乎变得不那么明确了。我编辑了,谢谢。
"现在 realloc(ptr, 0); 将释放旧内存,但没有明确定义下一步要做什么:它是实现定义的。" ——我也不确定那是对的。如果realloc
返回NULL
,则表示分配失败,并且在分配失败时,旧内存不会被释放。【参考方案4】:
realloc()
用于增加或减少内存,不用于释放内存。
Check this,并使用free()
释放内存(link)。
【讨论】:
【参考方案5】:void* realloc (void* ptr, size_t size);
在 C90 中:
如果 size 为零,则之前在 ptr 分配的内存将被释放,就像调用 free 一样,并返回一个空指针。
在 C99 中:
如果 size 为零,则返回值取决于特定的库实现:它可能是空指针或其他不应取消引用的位置。
【讨论】:
【参考方案6】:使用free(pointer); pointer = 0
代替realloc(pointer, 0)
。
【讨论】:
【参考方案7】:我会使用 realloc 给指针更多或更少的内存,但不会清空它。要清空指针,我会使用 free。
【讨论】:
"to empty" 指针不是通用表达式(至少在 C 编程的上下文中不是)。更重要的是它具有误导性,并且不适合free()
ing 指针引用的内存时发生的事情,指向。以上是关于释放分配的内存:realloc() 与 free()的主要内容,如果未能解决你的问题,请参考以下文章
内存动态分配之realloc(),malloc(),calloc()与new运算符
找出分配的内存是不是被 C 中的 realloc() 函数释放
梦开始的地方—— C语言动态内存管理(malloc+calloc+realloc+free)