如果realloc返回NULL,我是否需要释放旧内存?

3

我知道realloc()有两种方式。第一种方式是在新地址上分配内存并释放旧内存。第二种方式是在同一地址上分配内存,这样你只需要释放该地址即可。因此,在这两种情况下,你只需释放由realloc()分配的内存地址。但如果realloc()返回NULL,那么我需要像这样释放旧内存吗?:

//so in the first way, as b would be another address, a would be freed and if b is NULL it is no necessary to free it. But, if it follows second way, b will be same address as a and if it is NULL, I need to free old memory (a), right? 
int *a = (int*)malloc(sizeof(int));
int *b = (int*)realloc(a,sizeof(int)*3);

if(!b){
   free(a);
}

1
简短回答:是的。Linux上的man页面指出:“如果realloc()失败,则原始块保持不变;它不会被释放或移动。”更熟悉标准的人可能可以找到Posix或C99参考或类似参考资料。 - Max
2
C标准§7..22.3.5 realloc函数规定了其行为:如果无法为新对象分配内存,则不会释放旧对象,其值保持不变。 - Jonathan Leffler
1个回答

4
如果在这段代码片段中
int *a = (int*)malloc(sizeof(int));
int *b = (int*)realloc(a,sizeof(int)*3);

realloc函数在返回NULL后不会释放早期分配的内存。因此,在这种情况下,程序或函数的行为取决于上下文。您可以释放先前分配的内存。

free( a );

或者继续处理之前分配的内存,考虑到 realloc 失败的情况。


制作这样的代码会是一个不好的实践,因为我们会失去旧的内存,对吗? -> "int a = (int)malloc(sizeof(int)); a = (int*)realloc(a,sizeof(int)*3);" - Elrisas
1
正确。始终使用临时指针进行重新分配内存。这样,当(而不是如果)realloc失败时,您不会用NULL覆盖原始指针地址,从而创建内存泄漏。 - David C. Rankin
@来自莫斯科的Vlad,我有一个问题,如果realloc遵循第二种方式,如果你释放了(a),并且a的地址与b相同,那么如果你稍后决定释放(b),难道不是在进行双重释放吗?此外,如果你释放了a,重新分配的内存可能无法被引用。如果realloc遵循第二种方式,这是正确的吗? - Elrisas
1
如果realloc成功,那么原本由a指向的内存将被realloc释放,并且在将原始块的内容复制到新的重新分配的块中后,现在由b指向。只有在realloc失败的情况下,您才需要在使用完a后释放它。(以及为什么您不能安全地执行a = realloc(a, newsize);) - David C. Rankin
2
@Elrisas 第二种方式是什么?如果内存没有被重新分配,那么只有指针a有一个有效值,要释放它,你应该写free(a);如果内存成功地被重新分配,通常会写成a = b;指针b扮演中间指针的角色。否则,你需要使用仅存储在指针b中的值来释放内存。 - Vlad from Moscow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接