在新的放置缓冲区上调用析构函数?

时间:2015-05-17 04:14:13

标签: c++

所以我有这个课程

class Obj{           //simple class with constructor + destructor

  public:
  Obj(){cout<<"Obj1 has been created"<<endl;}
  ~Obj(){cout<<"Obj1 has been destroyed"<<endl;}
  };


  Obj * buffer[10];  //buffer



  int main(int argc, char *argv[])
  {
  Obj * c = new(&buffer[0]) Obj;
  delete &buffer[0];
  system("PAUSE");
  return EXIT_SUCCESS;
  }

这种使用展示位置的方法&#34; new&#34;一个有效的?因为当我尝试删除地址时,析构函数没有被调用。

但如果我使用这行代码,析构函数就会被调用

  Obj * c = new(&buffer[0]) Obj;
  delete c;

有人可以告诉我发生了什么吗?我真的必须删除指针来调出析构函数吗?

2 个答案:

答案 0 :(得分:4)

在示例中使用placement new以及尝试销毁它都是无效的:

  • 数组buffer包含指向Obj的指针。无法保证指针为对象提供足够的空间,或者指针正确对齐以保存对象的对象。
  • 要销毁使用placement new构造的对象,您需要一个类似于ptr->~Obj()的显式析构函数调用。

正确使用展示位置可能是这样的:

Obj*  objects[10];
char* buffers[10];
// ...
buffers[1] = new char[sizeof(Obj)];
objects[1] = new(buffers[1]) Obj();
// ...
objects[1]->~Obj();
delete[] buffers[1];

(显然,在实际代码中,您可以通过合适的RAII类来保护不同的缓冲区和对象,以避免资源泄漏。)

答案 1 :(得分:1)

使用placement new,您必须直接调用析构函数。

buffer[0].~Obj();

// or

c->~Obj();

您必须 NOT 调用对象上的删除,因为这会尝试释放内存。由于内存未分配新内存,因此未定义行为。

// delete &buffer[0];  Don't do this.