在C语言中,调用free()函数是否可能失败?

27

free() 调用会失败吗?

例如:

free(NULL);
6个回答

36

释放一个空指针不会失败。而且free函数不会返回任何错误,但释放未分配的内存、已经释放的内存或已分配块的中间部分是未定义行为 - 可能会导致内存错误并使程序中止(或更糟糕的是,它将损坏堆结构并在后续崩溃)。

甚至比这更糟糕的是,继续运行但完全破坏您的数据并将其写入磁盘,而你却没有察觉 :-)

标准文件(C99)的相关部分是第7.20.3.2节:

#include <stdlib.h>
void free(void *ptr);

free函数会释放指向ptr的空间,即可供进一步分配使用。如果ptr是空指针,则不执行任何操作。否则,如果参数与之前由callocmallocrealloc函数返回的指针不匹配,或者该空间已被freerealloc调用释放,则行为是未定义的。

free函数不返回任何值。


9
未定义行为最让人烦恼的是它有时候能够正常工作,而不是一定会出问题。请注意,“not will cause, may cause”翻译为“不会导致,可能导致”。 - paxdiablo
12
实际上最令人烦恼的事情是,它通常在一些广泛使用的平台上持续起作用,因此有无数开发人员认为这是可以接受的,因为“他们已经这样做很久了”。 - sharptooth
2
+1 是为了区分“失败”和未定义行为。你是对的,free 没有失败的情况。导致 UB 的无效输入是另一回事。 - Steve Jessop

6

除非你引起未定义行为(例如“双重释放”或尝试free()一个字符串常量),否则free()不会失败。


6

free(NULL)不做任何操作;对于一个不是通过相同的分配器(malloccalloc等)分配或已被释放的指针进行free操作是未定义的。由于free返回void,所以它失败的唯一方式是崩溃(例如段错误)。


2

是的,它可以在多种情况下失败。例如:

  1. 您释放了未动态分配的内容,例如栈上的变量。
  2. 您分配了一个指针,然后尝试释放指针 + 1。

1
free(NULL);

使用空指针调用free()是允许的,不会导致错误-参见:free() - Opengroup

使用已经被释放的指针调用free()通常会导致段错误并终止程序。


0
根据实现方式,free()可能会失败,例如在存在内存损坏的情况下:
char *p = malloc(1000);
*(p-1)=7;
free(p);

虽然这只是一个人为制造的例子,但类似的事情也可能发生在数组的末尾或开头。你可能第一次知道它是在free()中出现保护错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接