334

删除 NULL 指针是否安全?

它是一种好的编码风格吗?

4

8 回答 8

299

delete无论如何都会执行检查,因此在您身边进行检查会增加开销并且看起来更丑陋。一个非常好的做法是在之后将指针设置为 NULL delete(有助于避免双重删除和其他类似的内存损坏问题)。

delete如果默认情况下将参数设置为 NULL ,我也很喜欢

#define my_delete(x) {delete x; x = NULL;}

(我知道 R 和 L 值,但这不是很好吗?)

于 2010-11-16T02:38:46.957 回答
83

来自 C++0x 标准草案。

$5.3.5/2 - "[...]在任一替代方案中,delete 的操作数的值可能是空指针值。[...'"

当然,没有人会“删除”具有 NULL 值的指针,但这样做是安全的。理想情况下,不应该有删除 NULL 指针的代码。但是当指针的删除(例如在容器中)发生在循环中时,它有时很有用。由于删除 NULL 指针值是安全的,因此可以真正编写删除逻辑,而无需显式检查要删除的 NULL 操作数。

顺便说一句,C 标准 $7.20.3.2 还说 NULL 指针上的“免费”没有任何作用。

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

于 2010-11-16T02:38:24.323 回答
52

是的,它是安全的。

删除空指针没有害处;如果未分配的指针被初始化为零然后简单地删除,它通常会减少函数尾部的测试次数。


由于前面的句子引起了混淆,一个例子——不是例外安全的——描述的内容:

void somefunc(void)
{
    SomeType *pst = 0;
    AnotherType *pat = 0;

    …
    pst = new SomeType;
    …
    if (…)
    {
        pat = new AnotherType[10];
        …
    }
    if (…)
    {
        …code using pat sometimes…
    }

    delete[] pat;
    delete pst;
}

示例代码可以挑选出各种各样的细节,但这个概念(我希望)很清楚。指针变量被初始化为零,因此delete函数末尾的操作不需要在源代码中测试它们是否为非空;无论如何,库代码都会执行该检查。

于 2010-11-16T02:35:55.680 回答
22

删除空指针无效。这不一定是好的编码风格,因为它不是必需的,但它也不错。

如果您正在寻找良好的编码实践,请考虑使用智能指针,那么您根本不需要delete

于 2010-11-16T02:35:06.917 回答
12

为了补充ruslik 的回答,在 C++14 中,您可以使用以下构造:

delete std::exchange(heapObject, nullptr);
于 2017-11-08T15:01:47.993 回答
4

除非您重载删除运算符,否则它是安全的。如果您重载了 delete 运算符并且不处理 null 条件,那么它根本不安全。

于 2014-11-16T11:15:55.143 回答
0

有一个关于这个问题的常见问题解答可以回答这个问题。

C++ 语言保证,如果 p 为 null,则 delete p 不会执行任何操作。由于您可能会倒退测试,并且由于大多数测试方法强制您显式测试每个分支点,因此您不应该放入多余的 if 测试。

于 2021-03-05T17:21:06.103 回答
-4

我经历过 delete[] NULL (即数组语法)是不安全的(VS2010)。我不确定这是否符合 C++ 标准。

删除 NULL(标量语法)安全的。

于 2013-08-30T16:50:33.887 回答