2015-02-09 10 views
8

मैं कस्टम मेमोरी आवंटकों के साथ std::unique_ptr<T[]> का उपयोग करने का प्रयास कर रहा हूं।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() -methods जरूरत है और नि: शुल्क सरणियों: मूल रूप से, मुझे लगता है कि IAllocator है, जो निम्नलिखित तरीके प्रदान की उपवर्गों हैं कस्टम allocators है , वे रेंज में प्रत्येक तत्व पर आवंटित/मुक्त मेमोरी आवंटित करते हैं और T()/~T() पर कॉल करते हैं। अब, जहाँ तक मुझे पता है, कस्टम deleters 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* ऐसी जानकारी नहीं है, न तो अद्वितीय_ptr सरणी के आकार के बारे में जानता है (क्योंकि यह आपके द्वारा बताए गए सीधे delete [] का उपयोग करता है)। T स्वचालित रूप से विनाश को प्रबंधित करने के लिए unique_ptr<T> हो सकता है लेकिन यह संभव नहीं हो सकता है अगर पूरे संगत T* को स्मृति आवंटक द्वारा प्रबंधित किया जाता है (और एक T* ऑब्जेक्ट नहीं)। उदाहरण के लिए:

unique_ptr<unique_ptr<Foo>[]> data; 
data.reset(new unique_ptr<Foo>[50]); 
data[0].reset(new Foo()); 
संबंधित मुद्दे