调用 free 之前检查 NULL

发布于 2024-08-14 17:06:48 字数 140 浏览 6 评论 0原文

许多 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浅忆流年 2024-08-21 17:06:48

构造:

free(NULL);

在 C 中一直没问题,回到 Dennis Ritchie 编写的原始 UNIX 编译器。在预标准化之前,一些糟糕的编译器可能没有正确地处理它,但现在任何不这样做的编译器都不能合法地称自己为 C 语言编译器。使用它通常会产生更清晰、更易于维护的代码。

The construct:

free(NULL);

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.

柳若烟 2024-08-21 17:06:48

据我了解,对 NULL 的无操作并不总是存在。

在 C 的糟糕旧时光(回到过去
1986 年,基于 ANSI 之前的标准 cc
编译器) free(NULL) 会转储核心。
所以大多数开发人员之前都测试过 NULL/0
免费通话。

世界已经走过了漫长的道路,
看来我们不需要这样做
不再测试了但旧习惯会消失
很难;)

http://discuss.joelonsoftware.com/default.asp?design。 4.194233.15

As I understand, the no-op on NULL was not always there.

In the bad old days of C (back around
1986, on a pre-ANSI standard cc
compiler) free(NULL) would dump core.
So most devs tested for NULL/0 before
calling free.

The world has come a long way, and it
appears that we don't need to do the
test anymore. But old habits die
hard;)

http://discuss.joelonsoftware.com/default.asp?design.4.194233.15

迷爱 2024-08-21 17:06:48

我倾向于经常写“if (p) free(p)”,即使我知道不需要它。

我部分地责怪自己,因为我以前学过 C,当 free(NULL) 会出现段错误时,我仍然觉得不这样做会感到不舒服。

但我也责怪 C 标准不一致。例如,如果 fclose(NULL) 定义良好,我在书写时不会有问题:

free(p);
fclose(f);

这是清理事物时经常发生的事情。
不幸的是,我觉得写起来很奇怪

free(p);
if (f) fclose(f);

,我最终

if (p) free(p);
if (f) fclose(f);

知道,这不是一个合理的原因,但这就是我的情况:)

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:

free(p);
fclose(f);

Which is something that happens very often when cleaning up things.
Unfortunately, it seems strange to me to write

free(p);
if (f) fclose(f);

and I end up with

if (p) free(p);
if (f) fclose(f);

I know, it's not a rational reason but that's my case :)

若水般的淡然安静女子 2024-08-21 17:06:48

编译器,即使内联也不够聪明,无法知道函数将立即返回。将参数等压入堆栈并设置调用显然比测试指针更昂贵。我认为避免执行任何事情总是好的做法,即使该事情是空操作。
测试 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.

感情洁癖 2024-08-21 17:06:48

指针变量可能为 NULL 有两个不同的原因:

  1. 因为该变量用于类型理论中所谓的选项类型,并且保存指向对象的指针或 NULL表示什么都没有

  2. 因为它指向一个数组,因此如果数组长度为零,则可能为 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:

  1. 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,

  2. 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 to malloc(0) may return NULL. It is not meant as a general convenience, which is why for example fclose() does require a non-NULL argument. Abusing the permission to call free(NULL) by passing a NULL that does not represent a zero-length array feels hackish and wrong.

许久 2024-08-21 17:06:48

<前><代码>如果 (p)
免费(p);

为什么要进行另一次显式检查?

如果写了类似的东西,它是为了传达指针可能为NULL的特定知识......以帮助可读性和代码理解。因为将其作为断言看起来有点奇怪:

assert(p || !p);
free(p);

(除了看起来奇怪之外,如果您在许多此类情况下打开警告,编译器还会抱怨“条件始终为真”。)

所以我明白了如果上下文中不清楚的话,这是一个很好的做法。

相反的情况,即指针被期望为非空,通常从前面的代码行中可以明显看出:

...
Unhinge_Widgets(p->widgets);
free(p); // why `assert(p)`...you just dereferenced it!
...

但如果它不明显,那么拥有断言可能值得键入的字符。

if (p)
    free(p);

why another explicit check?

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:

assert(p || !p);
free(p);

(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:

...
Unhinge_Widgets(p->widgets);
free(p); // why `assert(p)`...you just dereferenced it!
...

But if it's non-obvious, having the assert may be worth the characters typed.

似狗非友 2024-08-21 17:06:48

在移动环境中可以有 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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文