sha*_*oth 17 c++ pointers memory-management
在阅读这个问题的答案时,我注意到答案(例如这个)意味着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;
}
Run Code Online (Sandbox Code Playgroud)
并且 - 令我惊讶的是 - Test::operator delete()通过ptr持有空指针来调用.
据我所知,它operator new分配内存operator delete并将内存返回给分配器.如果我delete在空指针上调用语句,则意味着指针后面没有对象,并且没有内存返回到分配器.
delete语句包括调用析构函数.当我传递一个空指针时,肯定不会调用析构函数--C++会处理这个问题.那么为什么operator delete在这种情况下被调用?
Ben*_*igt 19
即将推出的C++ 0x标准(第5.3.5节[expr.delete])中的语言如下:
如果delete-expression的操作数的值不是空指针值,则delete-expression将调用释放函数(3.7.4.2).否则,未指定是否将调用释放功能.[注意:无论对象的析构函数或数组的某个元素是否引发异常,都会调用释放函数. - 结束说明]
所以它是未指定的行为,一些编译器可能会operator delete在删除NULL指针时调用,而其他编译器可能不会.
编辑:标准使用的术语解除分配功能似乎引起了一些混乱.它附带一个参考.3.7.4.2中的一些关键语言[basic.stc.dynamic.deallocation]可能有助于澄清:
如果一个类
T具有operator delete仅使用一个参数命名的成员释放函数,则该函数是通常的(非放置)释放函数.
标准也很清楚,用户定义的operator delete需要接受一个空指针值的参数:
提供给解除分配函数的第一个参数的值可以是空指针值; 如果是这样,并且如果解除分配功能是标准库中提供的功能,则该调用无效.
但是由于5.3.5的未指定行为,operator delete当指针为空时,不应该依赖于被调用.
运算符删除就像任何其他运算符一样,为什么不调用它?它在调用之前无法检查其参数.
这就像operator+在你添加0时询问为什么被调用.