在阅读this question的答案时,我注意到答案(例如this)意味着即使在空指针上执行operator delete
语句,也可以调用delete
。
所以我写了一个小片段:
class Test {
public:
void* operator new( size_t ) { /*doesn't matter*/ return 0; }
void operator delete( void* ptr ) {
ptr; //to suppress warning and have a line to put breakpoint on
}
};
int main()
{
Test* ptr = 0;
delete ptr;
}
并且 - 令我惊讶的是 - Test::operator delete()
被调用,ptr
持有空指针。
据我所知,operator new
分配内存,operator delete
将内存返回给分配器。如果我在空指针上调用delete
语句,则意味着指针后面没有对象,并且没有内存可以返回到分配器。
delete
语句包括调用析构函数。当我传递一个空指针时,肯定不会调用析构函数--C ++会处理这个问题。那么为什么在这种情况下会调用operator delete
?
答案 0 :(得分:19)
即将推出的C ++ 0x标准(第5.3.5节[expr.delete]
)中的语言如下:
如果是操作数的值 delete-expression不是null 指针值,delete-expression 将调用释放功能 (3.7.4.2)。否则就是 未指定是否重新分配 函数将被调用。 [注意: 调用deallocation函数 无论是析构函数 对象或某些元素 数组抛出异常。 - 结束说明]
因此,这是未指定的行为,某些编译器可能会在删除NULL指针时调用operator delete
而其他编译器可能不会。{/ p>
编辑:标准使用的术语解除分配函数似乎引起了一些混乱。它附带一个参考。 3.7.4.2 [basic.stc.dynamic.deallocation]
中的一些关键语言可能有助于澄清:
如果类
T
具有名为operator delete
的成员释放函数 只有一个参数,那么该函数是一个通常的(非放置)释放函数。
标准也很清楚,用户定义的operator delete
需要接受一个空指针值的参数:
的价值 提供给释放函数的第一个参数可以是空指针值;如果是的话,如果解除分配 函数是标准库中提供的函数,调用无效。
但是由于5.3.5的未指定行为,当指针为空时,你不应该依赖于operator delete
被调用。
答案 1 :(得分:9)
操作员删除就像任何其他操作符一样,为什么不调用它?在调用之前,它无法检查的参数。
这就像询问为什么在添加0时调用operator+
。