删除 NULL 指针是否安全?
它是一种好的编码风格吗?
delete
。请改用 RAII。也就是说,使用 std::vector<T> v(100);
而不是 T* p = new T[100];
,使用像 unique_ptr<T>
和 shared_ptr<T>
这样的智能指针来处理删除而不是原始指针等。
make_shared
(c++11) 和 make_unique
(c++14) 您的程序应该包含 zero of new
和 delete
new
或 delete
。设计用于管理资源的类,标准组件无法完成工作,当然可以做他们需要做的事情,但关键是 他们用他们管理的内存做丑陋的事情,而不是最终用户代码。因此,创建您自己的库/帮助类来执行 new
/delete
,并使用该类代替它们。
delete
无论如何都会执行检查,因此在您这边进行检查会增加开销并且看起来更丑陋。 非常好的做法是在 delete
之后将指针设置为 NULL(有助于避免重复删除和其他类似的内存损坏问题)。
如果默认情况下 delete
将参数设置为 NULL ,我也很喜欢
#define my_delete(x) {delete x; x = NULL;}
(我知道 R 和 L 值,但这不是很好吗?)
来自 C++0x 标准草案。
$5.3.5/2 - "[...]在任一替代方案中,delete 的操作数的值可能是空指针值。[...'"
当然,没有人会“删除”具有 NULL 值的指针,但这样做是安全的。理想情况下,不应该有删除 NULL 指针的代码。但是当指针的删除(例如在容器中)发生在循环中时,它有时很有用。由于删除 NULL 指针值是安全的,因此可以真正编写删除逻辑,而无需显式检查要删除的 NULL 操作数。
顺便说一句,C 标准 $7.20.3.2 还说 NULL 指针上的“免费”没有任何作用。
free 函数会导致 ptr 指向的空间被释放,也就是说,可用于进一步分配。如果 ptr 是空指针,则不会发生任何操作。
是的,它是安全的。
删除空指针没有害处;如果未分配的指针被初始化为零然后简单地删除,它通常会减少函数尾部的测试次数。
由于前面的句子引起了混淆,一个例子——不是例外安全的——描述的内容:
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
操作不需要在源代码中测试它们是否为非空;无论如何,库代码都会执行该检查。
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
,那么就会有未定义的行为 - 虽然代码可以测试空性(x1
y1
) 在删除之前,不需要这样做。
删除空指针无效。这不一定是好的编码风格,因为它不是必需的,但它也不错。
如果您正在寻找良好的编码实践,请考虑改用智能指针,那么您根本不需要delete
。
除非您重载删除运算符,否则它是安全的。如果您重载了 delete 运算符并且不处理 null 条件,那么它根本不安全。
有一个关于这个问题的 FAQ 回答了这个问题。
C++ 语言保证,如果 p 为 null,则 delete p 不会执行任何操作。由于您可能会倒退测试,并且由于大多数测试方法强制您显式测试每个分支点,因此您不应该放入多余的 if 测试。
我经历过 delete[] NULL (即数组语法)是不安全的(VS2010)。我不确定这是否符合 C++ 标准。
删除 NULL(标量语法)是安全的。
delete[] NULL
是安全的。
不定期副业成功案例分享