在C语言中,释放一个空指针是否是一种好的做法?

108

可能重复的问题:
如果ptr是NULL,free(ptr)会损坏内存吗?

我正在编写一段C函数,用于释放已经通过 malloc() 函数分配的内存。指针可以是NULL(例如当出现错误时代码未能分配任何内存),也可以是通过malloc()分配的。使用free(ptr);而不是if (ptr != NULL) free(ptr);是否安全?

gcc甚至在使用-Wall -Wextra -ansi -pedantic选项编译时都没有警告,但这样做好不好?


重新打开。问题是:“...这是一个好的实践吗?”而不是“...这是合法的吗?”它们是两个不同的问题。我想知道释放空指针的理由,因为没有什么可以被释放。在我的脑海中,这毫无意义,而且是程序错误。 - jww
4个回答

199

引用C标准,来自ISO-IEC 9899的7.20.3.2/2:

void free(void *ptr);

如果ptr是空指针,则不执行任何操作。

不要检查NULL,这只会增加更多的冗余代码,因此是一种不好的做法。


但是,在使用malloc等函数时,您必须始终检查NULL指针。在这种情况下,NULL表示出了问题,很可能是没有可用内存。


我有一个包含指针的结构体。我尝试为它们分配内存。第一次分配失败(malloc()返回NULL),我调用释放函数,遍历所有指针并释放已经分配的内存。然后我发出错误信号。有更好的方法吗? - rid
1
@rdineiu,假设您在malloc调用之前将指针初始化为null(因此您永远不会释放未初始化的指针),那么这正是正确的方法。 - David X
3
这个 StackOverflow 链接中的一些回答提到,尽管 C 标准规定了一些内容,但某些 C 库会忽略这些规定并产生错误。值得注意。 - Abraham Philip
1
malloc和相似的函数指的是calloc()。 - jasonleonhard

32
检查指针是否为空再调用free函数是不必要的,这样只会让代码更加复杂。实际上,即使传入NULL指针,调用free函数也是安全的。根据C99标准第7.20.3.2/2节所述,“free”函数会释放由“ptr”指向的空间,并使其可供进一步分配使用。如果“ptr”是一个空指针,则不执行任何操作。需要注意的是,有些人可能认为检查是否为空比可能不必要的函数调用更有效率。然而,这是一种过早的微观优化。这种检查甚至可能成为一种悲观预测。例如,如果99%的指针不是NULL,则99%的时间都会进行冗余的NULL检查,以避免多余的函数调用1%的时间。

如果调用free会有开销,那么避免调用不是更有效率吗? - jww
1
可能是这样,但你必须问问自己,这种权衡是否值得。通常情况下,事情不会失败,你可能最终会获得已分配的内存而不是空指针。如果你在每个地方都添加空指针检查,这意味着你现在负面影响了常见情况的性能(并在代码中添加了混乱),只是为了避免在可能是非典型的故障情况下进行额外的函数调用。 - jamesdlin
@jww 逻辑上的开销不会超过 `if(ptr==NULL) return;',因此你自己检查所能达到的效果只是增加了一倍的开销! - Persixty
1
@Persixty 不完全准确,因为函数调用本身会产生开销。 - jamesdlin
@jamesdin 说得好。聪明的编译器可以内联检查,并仅在需要 free() 时调用。但我不知道真实的例子。因此,使用实际因素来衡量无效的 free() 调用是检查的6倍,您只有在超过5/6指针是非NULL时才能获胜。当然,在许多应用程序中,指针很少为非NULL。所以从实践角度看,你在2017年12月是正确的。这是一种权衡。 - Persixty

7

4
在我看来,不行,至少在你的情况下是不行的。
如果你无法分配内存,那么在调用free之前应该检查内存分配情况。

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