简体   繁体   English

我是否应该在使用多态分配器分配的 object 上调用“删除”

[英]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() ,具体取决于分配的方式。

Example 1: Allocator-Aware Container示例 1:分配器感知容器

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()的调用,我将把它作为练习来查看您的标准库实现是否会改变行为。

Example 2: Raw allocator use示例 2:原始分配器使用

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.

相关问题 我可以使用分配器对象来释放另一个分配器分配的内存吗? - Can I use an allocator object to free memory allocated by another allocator? 删除分配了新展示位置的动态多态对象 - Delete dynamic polymorphic object allocated with placement new polymorphic_allocator:何时以及为什么要使用它? - polymorphic_allocator: when and why should I use it? 使用由不同分配器分配的内存 - Using Memory Allocated by Different Allocator 如何在构造函数的参数中分配的对象上调用delete - how to call delete on an object that was allocated in the parameter for a constructor 自定义堆分配器 - 分配的对象必须指向分配器? - Custom heap allocator - the allocated object must point back to allocator? 使用delete关键字删除具有动态分配块的对象是否安全 - Is it safe to delete an object having a dynamically allocated block using delete keyword Protobuf:set_allocated_ *会删除分配的对象吗? - Protobuf: Will set_allocated_* delete the allocated object? 我应该将allocator作为函数参数传递吗? (我对分配器的误解) - Should I pass allocator as a function parameter? (my misunderstanding about allocator) 使用作用域的 `polymorphic_allocator` 和 `boost::circular_buffer` 失败 - Using scoped `polymorphic_allocator` with `boost::circular_buffer` fails
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM