如果调用析构函数并为其他对象再次使用分配的内存,会发生什么情况?

What happens if you call a destructor and use the allocated memory again for other objects?

class base
{
    virtual ~base();
};

class der1 :public base
{
    int i;
}

class der2 :public base //I used double that der2 is bigger than der1
{
    double d;
}

int main()
{
   base* ptr = new der2;
   ptr->~base(); //Destructor call just for the
                 //case that the der2 had a pointer member

   der1* ptr2 = static_cast<der1*>(ptr);
   *ptr2 = der1();

   delete ptr;

   return 0;
}

如果执行上面显示的代码会发生什么? 这会产生内存泄漏吗?如果是,为什么? 是否可以在不先释放内存的情况下将占用的内存用于不同类型? (请不要回答为什么你需要这个,这只是兴趣)

编辑: ~base() 什么都不做,因为这是一个例子。

这是未定义的行为,因为您在对象的生命周期结束后分配和删除对象,这是 C++11 所禁止的,[basic.life]/5:

after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. The program has undefined behavior if:

  • the object will be or was of a class type with a non-trivial destructor and the pointer is used as the operand of a delete-expression
  • the pointer is used to [...] call a non-static member function of the object

(加上一些其他限制。)您尝试同时做这两件事。

如果你要解决这个问题,通过在旧内存中创建一个新对象而不是分配给它,就好像那里已经有一个对象一样:

der1* ptr2 = new (ptr) der1;

那么它仍然是未定义的行为,如 C++11 中所述,[basic.life]/7

If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object [...] can be used to manipulate the new object, if [...] the new object is of the same type as the original object

(加上其他一些条件)。您使用指向旧对象的指针来操作(特别是删除)不同类型的新对象。