2015-02-09 81 views
8

我正在尝试使用std::unique_ptr<T[]>自定义内存分配器。基本上,我有一个是IAllocator,它提供了以下方法子类自定义的分配:std :: unique_ptr <T[]>和自定义分配器删除器

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<T[]>的情况下,通常你会打电话delete[]并用它做的,但我要叫FreeArray<T>,为此,我需要范围内的元素数量。鉴于只有原始指针,我认为没有获得范围的大小的方式,所以我能想出的唯一事情是这样的:

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

其中基本数组的大小将被传递手动删除对象。有一个更好的方法吗?这似乎很容易出错...

回答

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

T*不包含这样的信息,既不unique_ptr知道数组的大小(因为它直接使用delete []如你所述)。您可以让Tunique_ptr<T>来自动管理销毁,但如果整个连续T*由内存分配程序(而不是单个T*对象)管理,则无法执行此操作。例如:

unique_ptr<unique_ptr<Foo>[]> data; 
data.reset(new unique_ptr<Foo>[50]); 
data[0].reset(new Foo()); 
相关问题