我们可以使用 realloc 来释放动态分配的内存吗?
Posted
技术标签:
【中文标题】我们可以使用 realloc 来释放动态分配的内存吗?【英文标题】:Can we free dynamically allocation memory using realloc? 【发布时间】:2017-01-11 09:05:08 【问题描述】:我和我的朋友就释放动态分配的内存进行了讨论。他告诉我可以用 realloc() 来释放内存,但我拒绝了。 让我们考虑下面的代码:
int main()
int *p = (int *)malloc(sizeof(int) * 10);
int *q = (int *)malloc(sizeof(int) * 10);
free(p);
p = NULL;
realloc(q, sizeof(int) * 0);
q = NULL;
_getch();
return 0;
假设 p 和 q 分别指向地址 0x1000
和 0x2000
。
在上面的代码中,p 和 q 是int
指针,指向 RAM 中动态分配的 40 字节内存块。在执行 free(p)
时释放内存地址 (0x1000
)。释放的内存地址 (0x1000
) 可以再次被操作系统使用。然后,将 NULL 分配给指针变量p
,以防止p
成为悬空指针。
realloc(q, sizeof(int) * 0);
realloc()
只是将 q 指向的内存块缩小为零。但是 q 仍然指向同一个地址 (0x2000
),并且该地址没有被释放。在将 NULL 值分配给指针 q 时,q 现在指向 NULL,并且未释放 q 指向的地址 (0x2000
)并且该地址 (0x2000
) 的链接丢失。该地址 (0x2000
) 在程序结束之前不能被操作系统使用。
我的理解正确吗?
【问题讨论】:
你有什么证据表明q指向的东西没有被释放? 即使realloc()
的第二个参数为0,内存分配函数使用的堆中数据结构中的条目也不会被释放(不会返回到可用内存池) ,按设计使用的功能使用它们。
是的,您的理解是正确的,但有一点需要注意。通常当内存分配收缩时,实际保留的内存不会收缩
"realloc() 只是将 q 指向的内存块缩小到零。" --> 也许,也许不是。 C 没有指定realloc()
必须 以这种方式运行。这是一种多种可能性。
【参考方案1】:
realloc(, 0)
是 implementation dependent and not equivalent 到 free()
。
也就是说,你可能很幸运:
#include <stdio.h>
#include <malloc.h>
int main()
char *a;
a = malloc(1024);
printf("a = %08lx\n", a);
free(a);
a = malloc(1024);
printf("a = %08lx\n", a);
realloc(a, 0);
a = malloc(1024);
printf("a = %08lx\n", a);
gcc version 6.1.1 20160815 [gcc-6-branch revision 239479] (SUSE Linux)
ldd --version
ldd (GNU libc) 2.23
a = 01dad010
a = 01dad010
a = 01dad010
所以第二个 malloc,在 realloc(, 0) 之后,“看到”了一个空闲块,之前是 a。我认为这意味着在这种情况下,realloc
复制了free
的行为。 不要依赖这个。
【讨论】:
【参考方案2】:realloc(q, sizeof(int) * 0);
与
相同realloc(q, 0);
7.22.3.5 ->2 中的 C 标准 realloc 函数说:
..并返回一个指向新对象的指针,该对象的大小由 尺寸。新对象的内容应与新对象的内容相同 释放之前的旧对象,直到新旧对象中的较小者 尺寸。
但它没有明确指定如果新大小为零会发生什么。
但是您仍然有一个可以传递给free
的artist
指针。
考虑
char *a;
a=malloc(2*sizeof *a);
a=realloc(a,0);
// Note I'm purposely NOT using a temporary variable to store 'realloc' results
// Moreover, above is BAD practice.
free(a); // Is this permitted? YES !! Did we technically free memory above? NO !!
//Compiler will not yell at you for the above, in fact it is legal as per the standard
return 0; // No output for this one
对
char *a;
a=malloc(2*sizeof *a);
free(a);
//You're not suppose to free(a) again.
free(a);
//Compiler will yell at you for the above.
return 0;
输出
double free or corruption (fasttop): 0x0000000000915010
结论
deallocation
和 freeing
并不完全相同。
realloc
和free
都可以释放内存,但只有free
可以释放内存。
那是说
free(p);
p = NULL;
是释放内存的推荐方式。请检查[ this ] 答案。
【讨论】:
以上是关于我们可以使用 realloc 来释放动态分配的内存吗?的主要内容,如果未能解决你的问题,请参考以下文章
梦开始的地方—— C语言动态内存管理(malloc+calloc+realloc+free)
找出分配的内存是不是被 C 中的 realloc() 函数释放