2015-02-09 121 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()); 
相關問題