在 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() 返回的地址分配给同一个指针是一种好的编码习惯吗?