每次我分配新的位置时,都会隐式地称为destuructor
Destructor called implicitly every time I allocate with placement new
我有以下问题:我在项目自定义池分配器上使用,每当我将任何对象分配给其他对象时,destructor也会被暗中调用该对象。
这是源代码:
测试对象:
class Obj {
public:
Obj(const std::string& s) {
std::cout << "Constructor Called" << std::endl;
}
~Obj() {
std::cout << "Destructor Called" << std::endl;
}
};
主:
int main()
{
void *pmemory;
pmemory = malloc(ONEGIG_SIZE);
PoolAllocator* poolAllocator = new PoolAllocator(sizeof(Obj), __alignof(Obj), ONEGIG_SIZE, pmemory);
Obj *obj1 = allocator::allocateNew(*poolAllocator, Obj("Hello")); //<-- const and dest is called
//......
return 0;
}
这是分配器的源代码:分配功能:
template <class T> T* allocateNew(Allocator& allocator, const T& t)
{
return new (allocator.allocate(sizeof(T), __alignof(T))) T(t);
}
池分配器:
PoolAllocator::PoolAllocator(size_t objectSize, u8 objectAlignment, size_t size, void* mem)
: Allocator(size, mem), _objectSize(objectSize), _objectAlignment(objectAlignment)
{
ASSERT(objectSize >= sizeof(void*));
//Calculate adjustment needed to keep object correctly aligned
u8 adjustment = pointer_math::alignForwardAdjustment(mem, objectAlignment);
_free_list = (void**)pointer_math::add(mem, adjustment);
size_t numObjects = (size-adjustment)/objectSize;
void** p = _free_list;
//Initialize free blocks list
for(size_t i = 0; i < numObjects-1; i++)
{
*p = pointer_math::add(p, objectSize );
p = (void**) *p;
}
*p = nullptr;
}
PoolAllocator::~PoolAllocator()
{
_free_list = nullptr;
}
void* PoolAllocator::allocate(size_t size, u8 alignment)
{
ASSERT(size == _objectSize && alignment == _objectAlignment);
if(_free_list == nullptr)
return nullptr;
void* p = _free_list;
_free_list = (void**)(*_free_list);
_used_memory += size;
_num_allocations++;
return p;
}
void PoolAllocator::deallocate(void* p)
{
*((void**)p) = _free_list;
_free_list = (void**)p;
_used_memory -= _objectSize;
_num_allocations--;
}
看来,在池分配器中分配方法的返回o p之后,驱动器被调用!任何人都可以解释为什么会发生这种情况?
...每当我将任何对象分配给新的对象时,destuructor也会暗中列出该对象
no,在 and 对象上也称驱动器也被调用。您只是假设 - 错误地 - 被摧毁的对象是分配在池中的对象。
直觉上,由于您的allocateNew
函数将const ref作为某物作为参数,因此必须存在某物必须存在的参数,这意味着它是在您的池中分配任何内容之前就创建的。
详细说明,
Obj *obj1 = allocator::allocateNew(*poolAllocator, Obj("Hello"));
Will:
Obj("Hello")
使用
std::string
构造函数创建一个新的匿名临时对象,该对象将记录您看到的消息allocateNew(Allocator& allocator, const T& t)
将const ref转到您的
allocateNew
函数中。return new (...) T(t)
使用隐式生成的复制构造函数放置新的对象,它不记录任何内容
将指针返回到池中分配的新对象
在语句结束时销毁匿名临时性。
如果您想对正在发生的事情进行准确的图片,请实现登录版本 ash all 构造函数(和分配运算符(变体。
如果要避免临时对象 复制,请传递T&& t
并将构造移动到池中。
语句
Obj *obj1 = allocator::allocateNew(*poolAllocator, Obj("Hello"));
创建类型Obj
的临时性(来自Obj("Hello")
(,并通过参考allocator::allocateNew()
传递。
在功能中
template <class T> T* allocateNew(Allocator& allocator, const T& t)
{
return new (allocator.allocate(sizeof(T), __alignof(T))) T(t);
}
接收该临时对象为t
,new (allocator.allocate(sizeof(T), __alignof(T))) T(t)
创建了它的副本(在allocator.allocate()
提供的带有所提供的参数的内存中。这使用了复制构造函数,您的代码未跟踪。
当allocator::allocateNew()
返回,并且在控制传递到下一个语句之前,临时性被摧毁。
allocateNew()
中创建的副本继续存在。
在new
表达式产生的对象上,驱动器不会被隐式称为。它被要求用于临时。
this:'obj(" hello"('创建了一个临时性,用于在新位置中复制另一个对象。之后,暂时通过调用其破坏者。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 每次我分配新的位置时,都会隐式地称为destuructor