std :: unique_ptr <t []>和自定义分配器删除器</t []>

时间:2015-02-09 15:17:26

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

我正在尝试将std::unique_ptr<T[]>与自定义内存分配器一起使用。基本上,我有自定义分配器,它是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() / {{1} }在范围中的每个元素上。 现在,据我所知,~T()的自定义删除器使用签名:

std::unique_ptr

如果是void operator()(T* ptr) const ,通常您会调用unique_ptr<T[]>并完成它,但我必须调用delete[],我需要该范围内的元素数量。只给出了原始指针,我认为没有办法获得范围的大小,因此我唯一能想到的就是:

FreeArray<T>

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

2 个答案:

答案 0 :(得分:7)

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

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);

答案 1 :(得分:0)

T*不包含此类信息,unique_ptr也不知道数组的大小(因为它直接使用了delete [],如您所述)。您可以让T成为unique_ptr<T>来自动管理销毁,但如果整个连续的T*由内存分配器(而不是单个{{1}管理,则无法实现这一点。对象)。例如:

T*