我正在尝试将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>
基本上必须手动将数组的大小传递给删除对象。有一个更好的方法吗?这对我来说似乎很容易出错...
答案 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*