Alo*_*ave 26 c++ null delete-operator
这是代码审查评论之一.
在为任何对象调用delete之前检查NULL是个好主意吗?
我确实理解删除运算符在内部检查NULL并且是多余的,但是提出的参数是删除,因为运算符可以重载,如果重载版本没有检查NULL,它可能会崩溃.因此,假设如果和何时删除将被重载,它是否安全合理,它将检查是否为NULL?在我的理解中,合理地假设第一种情况是重载删除应该处理NULL检查,并且审查点不成立.你怎么看?
ybu*_*ill 35
不,不要检查null.标准说这delete (T*)0;是有效的.它只会使您的代码复杂化,没有任何好处.如果operator delete重载,最好在运算符的实现中检查null.只需保存代码行和错误.
编辑:这个答案被接受和赞成,但在我看来,它的信息量不大.这里的所有答案中都有一个缺失的部分,为了良心,让我在这里添加最后一部分.
该标准实际上在[basic.stc.dynamic]中说,至少从C++ 03开始:
C++程序中定义的任何分配和/或释放函数,包括库中的缺省版本,都应符合3.7.4.1和3.7.4.2中规定的语义.
引用的部分以及其他答案中列出的标准中的其他一些部分,表示传递空指针的语义是无操作.
在为任何对象调用delete之前检查NULL是个好主意吗?
没有!
int *p = NULL;
delete p ; //no effect
Run Code Online (Sandbox Code Playgroud)
标准说[第5.3.5/2节]
如果操作数具有类类型,则通过调用上述转换函数将操作数转换为指针类型,并使用转换后的操作数代替本节其余部分的原始操作数.在任一替代方案中,如果delete的操作数的值是空指针,则操作无效.
在节中 18.4.1.1/13
void operator delete(void* ptr) throw();
void operator delete(void* ptr, const std::nothrow_t&) throw();
默认行为:
- 对于ptr的空值,什么都不做.
- ptr的任何其他值应该是先前通过调用默认运算符new返回的值,该值不会被对operator delete(void*)的干预调用无效(17.4.3.7).对于ptr的这种非空值,回收先前调用默认运算符new分配的存储.
编辑:
詹姆斯坎泽在这里说
它仍然是操作员删除(或删除[])的响应性检查; 标准不保证不会给出空指针; 如果给出空指针,标准要求它是无操作.或者允许实现调用它.根据最新的草案,"提供给释放函数的第一个参数的值可能是空指针值;如果是,如果解除分配函数是标准库中提供的函数,则调用无效." 我不太确定"标准库中提供的那个"的含义是什么意思 - 从字面上看,因为他的功能不是标准库提供的,句子似乎不适用.但不知何故,这没有意义.
我会说,超载的责任delete就像你期望的那样delete.也就是说,它应该将 NULL指针作为无操作处理.
因此,调用一个重载的删除时,你应该不检查NULL.您应该依赖重载删除才能正确实现.