【问题标题】:std::unique_ptr<T[]> and custom allocator deleterstd::unique_ptr<T[]> 和自定义分配器删除器
【发布时间】:2015-04-09 09:14:46
【问题描述】:

我正在尝试将std::unique_ptr&lt;T[]&gt; 与自定义内存分配器一起使用。基本上,我有自定义分配器,它们是IAllocator 的子类,它提供以下方法:

void* Alloc( size_t size )
template<typename T> T* AllocArray( size_t count )
void Free( void* mem )
template<typename T> void FreeArray( T* arr, size_t count )

由于底层内存可能来自预先分配的块,我需要特殊的...Array()-方法来分配和释放数组,它们分配/释放内存并在每个元素上调用T()/~T()范围。 现在,据我所知,std::unique_ptr 的自定义删除器使用签名:

void operator()(T* ptr) const

unique_ptr&lt;T[]&gt; 的情况下,通常你会调用delete[] 并完成它,但我必须调用FreeArray&lt;T&gt;,为此我需要范围内的元素数量。仅给定原始指针,我认为无法获得范围的大小,因此我唯一能想到的是:

std::unique_ptr<T[], MyArrDeleter> somePtr( allocator.AllocArray<T>( 20 ), MyArrDeleter( allocator, 20 ) );

本质上,数组的大小必须手动传递给删除器对象。有一个更好的方法吗?这对我来说似乎很容易出错......

【问题讨论】:

    标签: c++ c++11 memory-management unique-ptr allocator


    【解决方案1】:

    是的,肯定有更好的方法:
    使用制造商功能。

    template<class T, class A> std::unique_ptr<T[], MyArrDeleter>
    my_maker(size_t count, A&& allocator) {
        return {somePtr(allocator.AllocArray<T>(count), MyArrDeleter(allocator, count)};
    }
    
    auto p = my_maker<T>(42, allocator);
    

    【讨论】:

      【解决方案2】:

      T* 不包含此类信息, unique_ptr 也不知道数组的大小(因为它直接使用 delete [] 如您所说)。您可以让T 成为unique_ptr&lt;T&gt; 以自动管理销毁,但如果整个连续的T* 由内存分配器(而不是单个T* 对象)管理,则这是不可能的。例如:

      unique_ptr<unique_ptr<Foo>[]> data;
      data.reset(new unique_ptr<Foo>[50]);
      data[0].reset(new Foo());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-30
        • 2017-05-15
        • 1970-01-01
        • 2015-08-13
        • 2019-01-16
        • 2018-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多