[英]Should I call `delete` on object allocated using polymorphic allocator
Does polymorphic allocator (I personally use boost and C++17, but guess that it's the same for stl and C++20) in it's destructor automatically destructs objects allocated inside it's memory resource, or should delete
for each object be called manually, like if I'm using default stl std::allocator
(where not calling delete
and then destructing object is an undefined behaviour)? Does polymorphic allocator (I personally use boost and C++17, but guess that it's the same for stl and C++20) in it's destructor automatically destructs objects allocated inside it's memory resource, or should
delete
for each object be called manually, like if I '我使用默认的 stl std::allocator
(不调用delete
然后破坏 object 是未定义的行为)?
A polymorphic allocator is a cheaply copyable object and doesn't own objects.多态分配器是可廉价复制的 object 并且不拥有对象。
What you might be confusing it with is a memory_resource
, which has capacity to store objects.您可能会混淆它的是
memory_resource
,它具有存储对象的能力。 Still, it doesn't own those, because it cannot even know the type(s) of object(s) stored in its capacity.尽管如此,它并不拥有这些,因为它甚至不知道存储在其容量中的对象的类型。
On the other hand, there are container types that use an allocator to allocate storage for their objects.另一方面,有些容器类型使用分配器为其对象分配存储空间。 The container does own the objects, and will destruct them and deallocate from the same (or rather, equivalent) allocator.
容器确实拥有这些对象,并将销毁它们并从相同的(或者更确切地说,等效的)分配器中释放它们。
In short, you will not be allocating from an allocator, your allocator-aware container will.简而言之,您不会从分配器进行分配,您的分配器感知容器会。 And it will not call delete, but rather the expectable
allocator.deallocate()
or allocator.delete_object()
depending on how the allocation was made.它不会调用 delete,而是调用预期的
allocator.deallocate()
或allocator.delete_object()
,具体取决于分配的方式。
Because an example speaks a thousand words:因为一个例子讲了一千个单词:
Live On Compiler Explorer Live On 编译器资源管理器
#include <iostream>
#include <memory_resource>
#include <vector>
struct X {
X() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
~X() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
int main() {
std::pmr::vector<X> v;
v.reserve(3); // watch v reallocate if you remove this line
v.emplace_back();
v.emplace_back();
v.emplace_back();
} // v destructs and deallocates automically
Prints:印刷:
X::X()
X::X()
X::X()
X::~X()
X::~X()
X::~X()
I'll leave it as an exercise to see whether your standard library implementation changes behaviour if you remove the call to reserve()
.如果您删除对
reserve()
的调用,我将把它作为练习来查看您的标准库实现是否会改变行为。
It's pretty clear that the allocator interface is not for direct consumption:很明显,分配器接口不能直接使用:
Live On Compiler Explorer Live On 编译器资源管理器
#include <iostream>
#include <memory_resource>
#include <vector>
struct X {
X() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
~X() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
};
int main() {
std::pmr::monotonic_buffer_resource mem(1024);
std::pmr::polymorphic_allocator<X> alloc(&mem);
{
auto x1 = alloc.new_object<X>();
auto x2 = alloc.new_object<X>();
auto x3 = alloc.new_object<X>();
// cannot use `operator delete`:
// delete x1; // Undefined Behaviour
// need to manually delete the objects we own through the allocator
alloc.delete_object(x3);
alloc.delete_object(x2);
alloc.delete_object(x1);
}
{ // c++17 interface
auto x1 = alloc.allocate(sizeof(X)); alloc.construct(x1);
auto x2 = alloc.allocate(sizeof(X)); alloc.construct(x2);
auto x3 = alloc.allocate(sizeof(X)); alloc.construct(x3);
// cannot use `operator delete`:
// delete x1; // Undefined Behaviour
// need to manually delete the objects we own through the allocator
alloc.destroy(x3); alloc.deallocate(x3, sizeof(X));
alloc.destroy(x2); alloc.deallocate(x2, sizeof(X));
alloc.destroy(x1); alloc.deallocate(x1, sizeof(X));
}
}
Prints印刷
X::X()
X::X()
X::X()
X::~X()
X::~X()
X::~X()
X::X()
X::X()
X::X()
X::~X()
X::~X()
X::~X()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.