记忆腐败

时间:2009-12-21 06:17:22

标签: c memory-leaks coredump

我正在运行一个小型的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!!
我错了吗?

7 个答案:

答案 0 :(得分:7)

根据手册页,“如果之前已经调用了free(ptr),则会发生未定义的行为。”

它不需要炸毁; “不做任何事情”是完全可以接受的未定义行为。也是鼻子恶魔。不要依赖它。

答案 1 :(得分:7)

您的计划存在多个问题:

  1. 由于您使用的是malloc()free(),因此在调用任何这些功能之前,您应该#include <stdlib.h>
  2. 不需要从malloc()转换返回值:它返回void *,可以安全地分配给任何其他指针类型(函数指针除外)。所以,您可以这样做:p = malloc(10);
  3. 释放由malloc()realloc()分配的指针后,以任何方式使用指针值都很糟糕:特别是,您无法再次调用free()
  4. int main()最好写成int main(void)
  5. 由于main()返回int,您应该从中返回一个值。传统上,0意味着成功。
  6. 当然,你的程序的主要(没有双关语)问题可以解决它多次,但上面提到的其他问题也很重要。一旦成功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中,可以优化它以更快地生成不可预测的行为。