当我在空指针上调用“delete”时,为什么会调用“operator delete”?

时间:2010-09-29 13:05:56

标签: c++ pointers memory-management

在阅读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

2 个答案:

答案 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+