问答中心分类: C++删除 NULL 指针是否安全?
0
匿名用户 提问 21分钟 前

删除 NULL 指针是否安全?
它是一种好的编码风格吗?

fredoverflow 回复 21分钟 前

好的做法是编写 C++ 程序而无需一次调用delete.利用RAII反而。也就是说,使用std::vector<T> v(100);代替T* p = new T[100];,使用智能指针,如unique_ptr<T>shared_ptr<T>负责删除而不是原始指针等。

fredoverflow 回复 21分钟 前

谢谢make_shared(c++11) 和make_unique(c++14) 你的程序应该包含newdelete

fredoverflow 回复 21分钟 前

可能仍然存在一些需要新建/删除的罕见情况,例如原子: 原子的&gt; 不允许和原子&gt; 在某些情况下,开销可能是不可接受的。

fredoverflow 回复 21分钟 前

要使用 RAII 声明一个具有资源管理的类,您需要调用 new 和 delete 对吗?或者您说有一些模板类可以隐藏这个。

fredoverflow 回复 21分钟 前

@VinGarcia 关键是大多数用户/客户(即:非库)代码永远不必编写new或者delete.旨在管理资源的类,标准组件无法完成的工作,当然可以做他们需要做的事情,但重点是他们用他们管理的内存做丑陋的事情,而不是最终用户代码。所以,做你自己的图书馆/助手类new/delete,并使用该类而不是它们。

6 Answers
0
Chubsdad 回答 21分钟 前

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

$5.3.5/2 – &quot;[…]在任一替代方案中,delete 的操作数的值可能是空指针值。[…'&quot;

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

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

codetaku 回复 21分钟 前

如果它没有故意在非优化代码中引入低效率,我真的很喜欢这个答案的引用。正如接受的答案所述,删除空指针是无操作的。因此,在删除指针之前检查指针是否为空是完全无关的。

0
Jonathan Leffler 回答 21分钟 前

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

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

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函数末尾的操作不需要在源代码中测试是否为非空;无论如何,库代码都会执行该检查。

user207421 回复 21分钟 前

我不得不读了几遍才能理解它。您一定是指在方法的顶部或在其期间将它们初始化为零,而不是在尾部,确定吗?否则,您只需同时删除归零和删除。

Jonathan Leffler 回复 21分钟 前

@EJP:函数的一个不完全不可信的轮廓可能是:void func(void) { X *x1 = 0; Y *y1 = 0; … x1 = new[10] X; … y1 = new[10] Y; … delete[] y1; delete[] x1; }.我没有展示任何块结构或跳转,但是delete[]由于开始时的初始化,最后的操作是安全的。如果某事跳到最后x1已分配和之前y1已分配并且没有初始化y1,那么就会有未定义的行为——而代码可以测试是否为空(x1y1) 在删除之前,没有必要这样做。

Andrew Steane 回复 21分钟 前

很高兴知道它是安全的。但是人们可能仍然使用“if (mypointer)”子句,因为它向阅读代码的人发出信号,表明所讨论的指针可能尚未设置,并且它表明这不是错误或尴尬,而是一部分设计(我承认也可以使用评论)。

0
Brian R. Bondy 回答 21分钟 前

删除空指针无效。这不一定是好的编码风格,因为它不是必需的,但它也不错。
如果您正在寻找良好的编码实践,请考虑使用智能指针,那么您不需要delete一点也不。

Tony Delroy 回复 21分钟 前

人们想要删除 NULL 指针的时间是当他们不确定它是否包含 NULL 时……如果他们知道它是 NULL 那么他们就不会考虑删除并因此询问;-)。

Brian R. Bondy 回复 21分钟 前

@Tony:我的意思只是它不会产生任何影响,并且删除有时包含 NULL 的指针的这种代码的存在并不一定是坏事。

paulm 回复 21分钟 前

IMO 冗余检查对于性能、可读性和可维护性来说肯定是不好的。

Winter 回复 21分钟 前

@paulm OP 当然不是在谈论那种坏事,更多的是 Seg Fault / UB 那种坏事。

0
ashrasmun 回答 21分钟 前

补充鲁斯利克的回答,在 C++14 中,您可以使用以下构造:

delete std::exchange(heapObject, nullptr);
0
user4016479user4016479 回答 21分钟 前

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

Marcin Nabiałek 回复 21分钟 前

您能否为您的答案添加任何解释?