我释放后仍然可以打印一个字符串?

我正在学习和测试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 ,它允许指向内存用于其他目的。 尝试读取或写入已释放的内存会调用未定义的行为 。

仅仅因为记忆已经放弃并不一定意味着它已被物理擦除。

打个比方:假设你在酒店房间的桌子上留了一本书。 您退房后,但仍有钥匙卡。 如果你回到房间,书可能在那里,或者可能没有。