释放后还能打印字符串吗?
Can still print a string after I freed it?
我正在学习和测试 C 中的内存分配,我想测试如果调用 free()
会发生什么。
我预计在我 运行 下面的程序之后可能会出现分段错误或指针是 NULL
。但是,我仍然可以像在输出中一样成功地打印字符串。我还尝试释放 str
两次,然后出现输出 2 错误。
看来之前分配的内存已经成功释放,但是内存上的数据并没有清理干净。那是对的吗?如果是这样,程序什么时候会清理那些释放的内存space?如果数据被释放但未清理,是否安全?
以上任何问题的答案都会有所帮助!谢谢!
代码
#include <stdio.h>
#include <stdlib.h>
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),这帮助我理解了之前让我感到困惑的其他事情,例如写入超出分配范围的字符串(如下面的代码片段中的内容)。根据wiki,这导致了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()
d 之后取消引用指针,您确实知道一件事,行为是未定义的。
当您调用free
时,它允许将指向的内存用于其他目的。尝试读取或写入已释放的内存会调用 undefined behavior.
仅仅因为内存已被放弃并不一定意味着它已被物理擦除。
打个比方:假设你在旅馆房间里落了一本书table。你退房了,但你还带着房卡。如果您回到房间,那本书 可能 还在,也可能不在。
我正在学习和测试 C 中的内存分配,我想测试如果调用 free()
会发生什么。
我预计在我 运行 下面的程序之后可能会出现分段错误或指针是 NULL
。但是,我仍然可以像在输出中一样成功地打印字符串。我还尝试释放 str
两次,然后出现输出 2 错误。
看来之前分配的内存已经成功释放,但是内存上的数据并没有清理干净。那是对的吗?如果是这样,程序什么时候会清理那些释放的内存space?如果数据被释放但未清理,是否安全?
以上任何问题的答案都会有所帮助!谢谢!
代码
#include <stdio.h>
#include <stdlib.h>
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),这帮助我理解了之前让我感到困惑的其他事情,例如写入超出分配范围的字符串(如下面的代码片段中的内容)。根据wiki,这导致了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()
d 之后取消引用指针,您确实知道一件事,行为是未定义的。
当您调用free
时,它允许将指向的内存用于其他目的。尝试读取或写入已释放的内存会调用 undefined behavior.
仅仅因为内存已被放弃并不一定意味着它已被物理擦除。
打个比方:假设你在旅馆房间里落了一本书table。你退房了,但你还带着房卡。如果您回到房间,那本书 可能 还在,也可能不在。