放置新和删除运算符时出现问题

Getting issue with placement new and delete operator

我编写了以下代码来放置新的和删除的运算符函数。你能用下面的代码告诉问题吗?

// new_operator.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
using namespace std;
class Mem
{
public:
    void* alloc(size_t sz) { return malloc(sz); }
    void dealloc(void* ptr) { free(ptr); }
};

class Object
{
public:
    Object() { cout << "In Constructor Object()" << this << endl; }
    ~Object() { cout << "In Destuctor ~Object()" << endl; }
    void* operator new(size_t sz, Mem* handle)
    {
        Object* x1 = (Object*)handle->alloc(sz);
        return x1;
    }
    void operator delete(void* ptr, Mem* handle)
    {
        cout << "Here\n";
        ((Object*)(ptr))->~Object();
        handle->dealloc(ptr);
    }
};
int main()
{
    Mem* memory = new Mem;
    Object* obj = new (memory) Object;
    cout << "Obj is " << obj << endl;
    delete (obj, memory);
    delete memory;
    return 0;
}

删除运算符函数开始执行时我遇到了运行时崩溃。谁能告诉我哪里做错了。

delete (obj, memory);

在这一行中,您只删除了 memory,没有删除 obj。逗号运算符的左手操作数被丢弃。由于表达式 obj 没有副作用,这可能是一个错误。

delete memory;

在这一行中,您再次删除 memory。这会导致未定义的行为。

请注意,您永远不会破坏您创建的动态 Object。只有在新放置抛出异常时才会调用自定义放置删除重载。在其他情况下,您的 malloc 会泄漏。

  1. 当从 placement new 调用的构造函数失败时,将调用 placement delete 以释放内存。您不应该从 operator delete 的任何版本调用任何析构函数,因为 operator delete 会释放在曾经驻留在那里的对象被销毁(或从未被构造为开始)后留下的内存。
  2. 显式调用放置运算符 delete 的唯一方法是拼出两个单词 operator delete,从而构成一个函数调用表达式。您不能从 delete-expression 调用它(没有 placement-delete-expression 语法)。在您的情况下,您需要使用限定名称:Object::operator delete。请注意,如果您从 Object::operator delete 中移除显式析构函数调用,因为上述原因,析构函数将不会被调用。无法在对放置删除的单个调用中同时调用析构函数和释放内存。处理这个问题的最简单方法是创建和使用非静态成员函数,比如 void Object::destroy(Mem*).