我释放后仍然可以打印一个字符串?
我正在学习和测试C中的内存分配,我想测试如果调用free()
会发生什么。
我预计在运行下面的程序后可能会出现分段错误或指针为NULL
。 但是,我仍然可以像输出一样成功打印字符串。 我还尝试将str
释放两次,然后在输出2发生时出现错误。
似乎先前分配的内存已成功解除分配,但内存中的数据未被清除。 那是对的吗? 如果是这种情况,程序什么时候会清理那些解除分配的内存空间? 如果数据被解除分配但没有清理,那是否安全?
上述任何问题的答案都会有所帮助! 谢谢!
码
#include #include int main() { printf("Hello, World!\n"); char *str = (char *)malloc(24); char *str2 = "tutorialspoint"; strcpy(str, str2); free(str); printf("[str] %s\n", str); return 0; }
产量
Hello, World! [str] tutorialspoint
输出2
main(83218,0x7fff9d2aa3c0) malloc: *** error for object 0x7fb0b2d00000: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug Abort trap: 6
编辑
谢谢大家的有益回复。 现在我明白C中有一些未定义的行为(UB),这有助于我理解其他让我困惑的东西,例如写入超出分配范围的字符串(就像下面的代码片段中的内容)。 这导致UB根据维基 ,但该程序不会崩溃。
如果我弄错了,请随意纠正我!
char *str = (char *)malloc(0); char *str2 = "tutorialspoint"; strcat(str, str2); printf("[str] %s, [addr] %p\n", str, str);
您需要学习未定义行为的概念。
即使您在释放字符串后打印它并且“ 工作 ”,但这并不意味着它有效。 这只是当行为被认为是未定义时可能发生的事情之一,在这种情况下它是。
此外,除非您执行此操作,否则指针不会为NULL
free(ptr); ptr = NULL;
和free()
,也没有将所有字节都设置为0
。
free()
函数就像它的名字所暗示的那样。 它允许malloc()
再次使用free()
d块。 指针指向的数据可能仍然保持不变,这就是为什么你仍然可以在free()
之后打印以前的内容的原因。 但是,如果你在free()
之后取消引用一个指针,或者数据是否仍然存在,或者被完全或部分覆盖,那么绝对不能保证会发生什么。
如果你在拥有free()
之后取消引用指针,那么有一件事你知道,行为是未定义的。
当您调用free
,它允许指向内存用于其他目的。 尝试读取或写入已释放的内存会调用未定义的行为 。
仅仅因为记忆已经放弃并不一定意味着它已被物理擦除。
打个比方:假设你在酒店房间的桌子上留了一本书。 您退房后,但仍有钥匙卡。 如果你回到房间,书可能在那里,或者可能没有。