调用 free 之前检查 NULL
许多 C 代码释放指针调用:
if (p)
free(p);
但是为什么呢?我认为 C 标准说 free 函数在给定 NULL 指针的情况下不会执行任何操作。那么为什么还要进行另一次显式检查呢?
Many C code freeing pointers calls:
if (p)
free(p);
But why? I thought C standard say the free
function doesn't do anything given a NULL pointer. So why another explicit check?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
构造:
在 C 中一直没问题,回到 Dennis Ritchie 编写的原始 UNIX 编译器。在预标准化之前,一些糟糕的编译器可能没有正确地处理它,但现在任何不这样做的编译器都不能合法地称自己为 C 语言编译器。使用它通常会产生更清晰、更易于维护的代码。
The construct:
has always been OK in C, back to the original UNIX compiler written by Dennis Ritchie. Pre-standardisation, some poor compilers might not have fielded it correctly, but these days any compiler that does not cannot legitimately call itself a compiler for the C language. Using it typically leads to clearer, more maintainable code.
据我了解,对 NULL 的无操作并不总是存在。
http://discuss.joelonsoftware.com/default.asp?design。 4.194233.15
As I understand, the no-op on NULL was not always there.
http://discuss.joelonsoftware.com/default.asp?design.4.194233.15
我倾向于经常写“
if (p) free(p)”,即使我知道不需要它。
我部分地责怪自己,因为我以前学过 C,当
free(NULL)
会出现段错误时,我仍然觉得不这样做会感到不舒服。但我也责怪 C 标准不一致。例如,如果 fclose(NULL) 定义良好,我在书写时不会有问题:
这是清理事物时经常发生的事情。
不幸的是,我觉得写起来很奇怪
,我最终
知道,这不是一个合理的原因,但这就是我的情况:)
I tend to write "
if (p) free(p)
" a lot, even if I know it's not needed.I partially blame myself because I learned C the old days when
free(NULL)
would segfault and I still feel uncomfortable not doing it.But I also blame the C standard for not being consistent. Would, for example, fclose(NULL) be well defined, I would not have problems in writing:
Which is something that happens very often when cleaning up things.
Unfortunately, it seems strange to me to write
and I end up with
I know, it's not a rational reason but that's my case :)
编译器,即使内联也不够聪明,无法知道函数将立即返回。将参数等压入堆栈并设置调用显然比测试指针更昂贵。我认为避免执行任何事情总是好的做法,即使该事情是空操作。
测试 null 是一个很好的做法。更好的做法是确保您的代码不会达到这种状态,从而完全消除测试的需要。
Compilers, even when inlining are not smart enough to know the function will return immediately. Pushing parameters etc on stack and setting the call up up is obviously more expensive than testing a pointer. I think it is always good practice to avoid execution of anything, even when that anything is a no-op.
Testing for null is a good practice. An even better practice is to ensure your code does not reach this state and therefore eliminate the need for the test altogether.
指针变量可能为 NULL 有两个不同的原因:
因为该变量用于类型理论中所谓的选项类型,并且保存指向对象的指针或 NULL表示什么都没有,
因为它指向一个数组,因此如果数组长度为零,则可能为 NULL(因为允许
malloc(0)
返回 NULL,实现定义的)。尽管这只是逻辑上的区别(在 C 中,既没有选项类型,也没有特殊的指向数组的指针,我们只是使用指针来处理所有事情),但应该始终明确如何使用了一个变量。
C 标准要求
free(NULL)
不执行任何操作,这与成功调用malloc(0)
可能返回NULL
的事实是必要的对应。代码>.它并不意味着一般的便利,这就是为什么fclose()
确实 需要非 NULL 参数。通过传递不代表零长度数组的 NULL 来滥用调用free(NULL)
的权限,感觉很黑客且错误。There are two distinct reasons why a pointer variable could be NULL:
because the variable is used for what in type theory is called an option type, and holds either a pointer to an object, or NULL to represent nothing,
because it points to an array, and may therefore be NULL if the array has zero length (as
malloc(0)
is allowed to return NULL, implementation-defined).Although this is only a logical distinction (in C there are neither option types nor special pointers to arrays and we just use pointers for everything), it should always be made clear how a variable is used.
That the C standard requires
free(NULL)
to do nothing is the necessary counterpart to the fact that a successful call tomalloc(0)
may returnNULL
. It is not meant as a general convenience, which is why for examplefclose()
does require a non-NULL argument. Abusing the permission to callfree(NULL)
by passing a NULL that does not represent a zero-length array feels hackish and wrong.如果我写了类似的东西,它是为了传达指针可能为NULL的特定知识......以帮助可读性和代码理解。因为将其作为断言看起来有点奇怪:
(除了看起来奇怪之外,如果您在许多此类情况下打开警告,编译器还会抱怨“条件始终为真”。)
所以我明白了如果上下文中不清楚的话,这是一个很好的做法。
相反的情况,即指针被期望为非空,通常从前面的代码行中可以明显看出:
但如果它不明显,那么拥有断言可能值得键入的字符。
If I write something like that, it's to convey the specific knowledge that the pointer may be NULL...to assist in readability and code comprehension. Because it looks a bit weird to make that an assert:
(Beyond looking strange, compilers are known to complain about "condition always true" if you turn your warnings up in many such cases.)
So I see it as good practice, if it's not clear from the context.
The converse case, of a pointer being expected to be non null, is usually evident from the previous lines of code:
But if it's non-obvious, having the assert may be worth the characters typed.
在移动环境中可以有 free() 的自定义实现。
在这种情况下,free(0) 可能会导致问题。
(是的,实施不好)
there can be a custom implementation of free() in mobile environment.
In that case free(0) can cause a problem.
(yeah, bad implementation)