我正在运行一个小型的c程序:
#include<stdio.h>
int main()
{
char *p;
p = (char *)malloc(10);
free(p);
free(p);
free(p);
printf("\npointer is freed!!\n");
}
基本上我释放已经被释放的内存。 我认为应该导致核心转储!!是不是这样?
但它正在打印
pointer is freed!!
我错了吗?
答案 0 :(得分:7)
根据手册页,“如果之前已经调用了free(ptr),则会发生未定义的行为。”
它不需要炸毁; “不做任何事情”是完全可以接受的未定义行为。也是鼻子恶魔。不要依赖它。
答案 1 :(得分:7)
您的计划存在多个问题:
malloc()
和free()
,因此在调用任何这些功能之前,您应该#include <stdlib.h>
。malloc()
转换返回值:它返回void *
,可以安全地分配给任何其他指针类型(函数指针除外)。所以,您可以这样做:p = malloc(10);
malloc()
或realloc()
分配的指针后,以任何方式使用指针值都很糟糕:特别是,您无法再次调用free()
。int main()
最好写成int main(void)
。main()
返回int
,您应该从中返回一个值。传统上,0意味着成功。当然,你的程序的主要(没有双关语)问题可以解决它多次,但上面提到的其他问题也很重要。一旦成功free()
'da指针,就调用它上面的free()
是未定义的行为:程序可以执行任何操作,包括(不幸的是),似乎没有做任何不好的事情 。我说“不幸”,因为它可能会给你一种安全感,可以不止一次free()
一个指针。
答案 2 :(得分:1)
释放已经释放的内存,导致未定义的行为,你很幸运,在这种情况下,在其他时候你可能会得到你的核心转储
答案 3 :(得分:1)
只是为了添加其他答案,我想要注意,如果将指针设置为NULL然后调用free(),则行为将不再是未定义的。这几乎是一个无操作。但是,如果指针被释放并且在将指针指向另一个位置(甚至是NULL)之前再次对其调用free(),则无法确定会发生什么。它可能导致某些实现上的核心转储,而其他一些实现则不会发生任何事情。
答案 4 :(得分:0)
它取决于实现此功能的操作系统(linux,windows ...)的实现。根据操作系统(未定义的行为),它们的行为可能会有所不同,因此您不能依赖它们,并且您必须在程序中只释放一次所有已分配的内存。
编辑:它不是操作系统的一部分,而是标准库的一部分,因操作系统而异。
答案 5 :(得分:0)
堆损坏不一定会立即导致问题。可能会发生释放的内存(或内存的一部分)用于分配其他一些结构,然后它可能会导致问题。 free
记忆不止一次总是UB(未定义),即使你当时没有看到邪恶的影响,也不应该这样做。
答案 6 :(得分:0)
我希望大多数编译器的DEBUG构建能够检测到这种类型的故障并准确报告发生了什么。 MSVC也会如此。
在RELEASE中,可以优化它以更快地生成不可预测的行为。