我的代码存在一些混淆。
我使用malloc()分配内存,释放它,然后使用与参数相同的指针ptr调用realloc(),但不要使用realloc的返回地址。
此代码编译并运行精细打印预期的字符串。我没想到它因为ptr之前被释放了。
但是,如果我将realloc()的返回地址分配给ptr而不是注释掉,那么当然会有预期的运行时错误,因为ptr将为NULL。
如果我只是将之前释放的ptr作为参数传递,它为什么会起作用。它显然再次分配内存?提前谢谢。
注意:此代码是故意编写的,目的只是为了尝试了解后台发生的情况。当然不建议取消引用悬空指针等。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* ptr;
ptr = (char*)malloc(20);
strcpy(ptr, "Hello");
printf("Address before free : %d\n", ptr);
printf("%s\n", ptr);
free (ptr);
printf("Address after free : %d\n", ptr);
printf("%s\n", ptr);
realloc(ptr, 30);
//ptr = realloc(ptr, 30); // causes runtime problem as expected
strcpy(ptr, "Hello");
printf("Address after realloc : %d\n", ptr);
printf("%s\n", ptr);
return 0;
}
答案 0 :(得分:6)
对于realloc()
,具体而言,引用C11
标准,章节§7.22.3.5
如果
ptr
是空指针,则realloc
函数的行为类似于malloc
函数 指定大小。否则,如果ptr
与先前由内存返回的指针不匹配 管理功能,或者如果通过调用free
或已释放空间realloc
函数,行为未定义。 [....]
也就是说,在这种情况下,您调用了 undefined behavior 在此之前,通过说
printf("Address after free : %d\n", ptr);
printf("%s\n", ptr);
错误在哪里
%p
是指针所需的格式说明符,其中参数已转换为void *
,而不是%d
free()
- d memory ,单独和单独都足以调用UB。
底线:在将指针传递给free()
之前不要尝试realloc()
指针,它会自行处理。
答案 1 :(得分:2)
名为realloc()
的函数将重新分配内存区域,前提是它先前已分配malloc()
calloc()
,或realloc
且尚未释放强烈打电话给free()
。如果在free()
之前的某个内存上调用realloc()
将导致未定义的行为。不要将realloc()
与已经释放的内存一起使用。
最诚挚的问候!
答案 2 :(得分:0)
程序的正确和演示版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char* ptr;
ptr = malloc(20);
strcpy(ptr, "Hello");
printf("Address : %p\n", (void*)ptr);
printf("%s\n", ptr);
ptr = realloc(ptr, 30); // expand the memory pointed by ptr
// from 20 to 30 bytes.
printf("Address after realloc : %p\n", (void*)ptr); // address most likely different
printf("%s\n", ptr); // displays still "Hello"
// as realloc preserves memory content
free(ptr); // eventually free what has been allocated previously
return 0;
}
示例输出:
Address : 00767BC8
Hello
Address after realloc : 00768C38
Hello
BTW:realloc之前和之后的地址可能是相同的,具体取决于实现。
尝试重新分配更少的内存(例如18),地址很可能是相同的,但这仍然依赖于实现。
答案 3 :(得分:0)
ptr = realloc(ptr,30);
这很糟糕。如果重新分配失败,例如没有足够的内存并返回零,那么您松开了原来的指针,那儿就出现了内存泄漏