在使用operator new的展示位置删除结果上调用delete好吗?

时间:2013-05-23 23:57:24

标签: c++ new-operator delete-operator placement-new

如果我这样做

struct MyStruct { ~MyStruct() { } };

void *buffer = operator new(1024);
MyStruct *p = new(buffer) MyStruct();
// ...
delete p;     //    <---------- is this okay?

delete是否可以保证两者调用~MyStruct() 以及 operator delete

3 个答案:

答案 0 :(得分:13)

delete p相当于

p->~MyStruct();
operator delete(p);

除非MyStruct有替代operator delete,否则您的示例应该使用预期的语义进行良好定义。

[expr.delete]/2州:

  

delete的操作数的值可以是......指向前一个 new-expression 创建的非数组对象的指针。

Placement new是一种 new-expression [expr.new]/1

  

新表达的:
  :: opt new new-placement opt new-type-id new-initializer 选择
  :: opt new new-placement opt type-id new-initializer opt

delete被定义为对对象的析构函数的调用,然后调用内存的释放函数。 [expr.delete]/6,7

  

... delete-expression 将调用对象的析构函数(如果有的话)......

     

... delete-expression 将调用释放函数...

只要解除分配函数与分配函数匹配(只要你没有为你的类重载operator delete),那么这一切都应该很好地定义。

答案 1 :(得分:12)

[已修订]通常情况下并不正常,您通常只能delete使用匹配的普通new表达式获得的内容。否则,您可以保证解除分配函数与分配函数匹配(因此,假设您的原始::delete p;位于全局命名空间中,使用operator new将是更安全的通用解决方案。特别是当有问题的类(或其派生类之一)超载operator new时,你必须小心。

由于您正在使用placement-new表达式来创建*p,并且由于没有“placement-delete expression”这样的东西,您必须手动销毁该对象然后释放内存:

p->~MyStruct();

operator delete(buffer);

答案 2 :(得分:0)

不,你通常不应该调用delete(在某些情况下,例如当操作员删除被过度使用时,可能没问题)。

char *buffer = new char[1024];
MyStruct *p = new(buffer) MyStruct(); //placement new "i'm just calling constructor"
p->~MyStruct();  //destroy the object.

//delete p; // WHAT? even if you override operator delete it may be opaque to reader.
delete [] buffer; // THIS DELETE IS OK (if you have first destroyed MyStruct)
相关问题