释放分配的内存: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 void *realloc(void *ptr, size_t 大小); 描述 2 realloc函数释放ptr指向的旧对象并返回一个 指向具有 size 指定大小的新对象的指针。新的内容 对象应与释放前的旧对象相同,直至两者中的较小者 新旧尺寸。新对象中超出旧对象大小的任何字节都有 不确定的值。 3 如果 ptr 是空指针,则 realloc 函数的行为类似于 malloc 函数 规定的大小。否则,如果 ptr 与内存先前返回的指针不匹配 管理功能,或者如果空间已通过调用 free 或 realloc 函数,行为未定义。如果新对象的内存不能 已分配,旧对象不会被释放,其值不变。 退货 4 realloc 函数返回一个指向新对象的指针(可能具有相同的 值作为指向旧对象的指针),或者如果新对象不能是空指针 分配。

如您所见,它没有为大小为 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)

动态内存函数+经典笔试题@动态内存管理---malloc +free + calloc + realloc

动态内存分配与静态内存分配

C语言中free函数的用法