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