【问题标题】:Getting issue with placement new and delete operator放置 new 和 delete 运算符出现问题
【发布时间】:2021-06-20 12:48:20
【问题描述】:

我已经编写了以下代码来放置 new 和 delete 运算符函数。能否请您用下面的代码说明问题。

// 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;
}

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

【问题讨论】:

  • 你认为这是做什么的? (obj, memory)
  • 为什么要在分配给Mem的空间中存储Object
  • delete (obj, memory); 中,您正在调用comma operator,因此该语句实际上与delete memory; 相同,您随后也会立即调用。因此,您delete 使用相同的memory 两次。此外,您不能 delete 使用 placement-new 创建的对象,因为它会尝试释放未使用 new 分配的内存。
  • @DavidC.Rankin operator new 函数分配字节,而不是对象。
  • @DavidC.Rankin 不,operator new 的成员版本仍然分配原始字节。它不应该构造任何类对象。 malloc 就好了。

标签: c++ operator-overloading dynamic-memory-allocation new-operator delete-operator


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

【讨论】:

    【解决方案2】:
    delete (obj, memory);
    

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

    delete memory;
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 2012-08-04
      • 2014-03-26
      • 2011-06-11
      • 1970-01-01
      • 2013-03-12
      相关资源
      最近更新 更多