在 C 中释放 NULL 指针是一种好习惯吗? [复制]

Posted

技术标签:

【中文标题】在 C 中释放 NULL 指针是一种好习惯吗? [复制]【英文标题】:Is it good practice to free a NULL pointer in C? [duplicate] 【发布时间】:2011-08-30 08:45:20 【问题描述】:

可能重复:Does free(ptr) where ptr is NULL corrupt memory?

我正在编写一个 C 函数,如果它是 malloc()ed,则释放指针。指针可以为 NULL(在发生错误且代码没有机会分配任何内容的情况下)或使用malloc() 分配。使用free(ptr); 代替if (ptr != NULL) free(ptr); 是否安全?

gcc 一点也不抱怨,即使是-Wall -Wextra -ansi -pedantic,但这是一种好的做法吗?

【问题讨论】:

另见:checking for null before calling free 重新打开。问题是,"...这是一种好习惯吗";而不是 :...它是否合法"。它们是两个不同的问题。我很想知道释放 NULL 指针的理由,因为没有任何东西可以被释放。在我看来,它使没有意义,这是一个程序错误。 【参考方案1】:

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

void free(void *ptr);

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

不要检查NULL,它只会添加更多要读取的虚拟代码,因此是一种不好的做法。


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

【讨论】:

我是。我有一个包含指针的结构。我尝试分配它们中的每一个。第一次分配失败(malloc() 返回的指针为 NULL)时,我调用释放函数,该函数遍历所有这些并释放已分配的那些。然后我发出错误信号。有没有更好的方法来做到这一点? @rdineiu,假设您在调用 malloc 之前将指针初始化为 null(因此您永远不会 free 未初始化的指针),这正是这样做的正确方法。 此 *** 链接上的一些答案:***.com/questions/1938735/… 提到某些 C 库忽略此标准并抛出错误,尽管 C 标准说了什么。可能值得一看。 "malloc & co."你的意思是 calloc()【参考方案2】:

在调用free 之前不要费心检查NULL 是个好习惯。检查只会给你的代码增加不必要的混乱,free(NULL) 保证是安全的。来自 C99 标准的第 7.20.3.2/2 节:

free 函数使ptr 指向的空间被释放,也就是说,可用于进一步分配。如果ptr 是空指针,则不执行任何操作。

正如 cmets 中所述,有些人有时想知道检查 NULL 是否比进行可能不必要的函数调用更有效。但是,这个:

是过早的微优化。 应该没关系。首先检查NULL 甚至可能是一种悲观。例如,如果 99% 的情况下您的指针不是 NULL,那么在 99% 的情况下将有一个冗余的 NULL 检查以避免 1% 的时间进行额外的函数调用。

【讨论】:

如果对free 的调用有开销怎么办。避免调用不是更有效率吗? @jww 可能是这样,但你必须问问自己这种权衡是否值得。 common 情况是事情不会失败,并且您最终可能会得到分配的内存而不是空指针。如果您在各处添加空指针检查,这意味着您现在已经对常见案例的性能产生了负面影响(并为您的代码添加了混乱),只是为了避免在可能是非典型故障案例中的额外函数调用。 @jww 开销逻辑上不超过 `if(ptr==NULL) return;'因此,通过检查自己,您所能期望的只是将开销加倍! @Persixty 不完全是因为函数调用本身会产生开销。 @jamesdin 公平点。智能编译器可以内联检查,并且仅在需要 free() 时调用。但我知道没有真实的例子。因此,使用一个现实因素,即对free() 的无能调用是您赢得检查的 6 倍,除非超过 5/6 的指针是非空的。当然,在许多应用程序中,指针很少是非 NULL 的。所以实际上你在 2017 年 12 月是对的。这是一个权衡。【参考方案3】:

参见http://linux.die.net/man/3/free 声明:

如果 ptr 为 NULL,则不执行任何操作。

【讨论】:

【参考方案4】:

在我看来,不,至少不是你的情况。

如果你不能分配内存,你应该在调用 free 之前检查那个 WAY。

【讨论】:

以上是关于在 C 中释放 NULL 指针是一种好习惯吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在每个可能的地方都使用指针是一种好习惯吗? [复制]

将 realloc() 返回的地址分配给同一个指针是一种好的编码习惯吗?

使用引用来布置简单的功能是一种好习惯吗

在 C 中使用第一个数组元素作为数组长度是一种好的编程习惯吗?

在 perl 中使用嵌套映射是一种好习惯吗?

在“for”循环条件中使用“三元运算”是一种好习惯吗?