2012-07-26 13 views
5

मैं वर्तमान में ओपनजीएल के साथ निचले स्तर के कोडिंग के लिए सी ++ में खुद को प्राप्त कर रहा हूं। मैं एक भारी objc पृष्ठभूमि से आया है इसलिए मुझे स्मृति प्रबंधन के बारे में कुछ समझ है लेकिन मुझे लगता है कि "बूस्ट" लाइब्रेरी ptr_vector जैसे कंटेनर प्रकारों का प्रबंधन कैसे करती है।ptr_vector स्मृति का प्रबंधन कैसे करता है?

मुझे लगता है कि मेरी समस्या इस तथ्य से संबंधित है कि मुझे नहीं पता कि ptr_vector अपने और अपने वस्तुओं के विनाश का प्रबंधन कैसे करता है।

कृपया निम्नलिखित कोड पर एक नज़र डालें:

// Header file 
... 
ptr_vector<IObject3D> objects; 
... 

// Implementation file 
... 
void ApplicationEngine::init() 
{ 
    WavefrontObject3D *object = new WavefrontObject3D("Ninja.obj"); 
    objects.push_back(object); 
} 
... 

तो, वास्तव में सवाल के लिए: मैं "वस्तु" चर के माध्यम से यहां एक रिसाव बनाने रहा हूँ?

मैं बनाए रखने और ObjC में स्पष्ट कॉल के साथ मैन्युअल रूप से मेरी वस्तुओं जारी करने के लिए प्रयोग किया जाता है: पहले मैं WavefrontObject3D objectalloc init था, एक सरणी में जोड़ने और बाद में release कि एक ही वस्तु लीक से बचने के लिए।

लेकिन जब मैं delete object जोड़ता हूं तो push_back के बाद वेवफ़्रंटऑब्जेक्ट 3 डी object के deconstructor को कॉल किया जाता है। यह मुझे एक संकेत देता है कि ptr_vectorobject चर को बनाए रखता नहीं है। क्या मेरी धारणा सही है?

अतिरिक्त है, लेकिन संबंधित, प्रश्न: मान लीजिए कि मैं युक्त वर्ग ApplicationEngine नष्ट करने के लिए नहीं चाहिए मैं ptr_vector या तत्वों यह प्रबंधन करता है पर Deconstructor किसी तरह का कॉल करनी होगी है?

+0

'लेकिन जब मैं पुश_बैक कॉल के बाद एक डिलीट ऑब्जेक्ट जोड़ता हूं तो WavefrontObject3D ऑब्जेक्ट के deconstructor को कॉल किया जाता है। 'वैसे यही है' हटाने 'के लिए बनाया गया है। यह पॉइंटर पॉइंट्स के उदाहरण पर विनाशक को बुलाता है। – Nobody

+1

मुझे लगता है कि आपको [RAII] (http://stackoverflow.com/q/395123/20984) पर पढ़ना चाहिए, जिस तरह से तथाकथित "आधुनिक" सी ++ में अधिकांश मेमोरी प्रबंधन किया जाता है। –

+0

ग्रेट रिसोर्स @ ल्यूकौराइल! वास्तव में जिस तरह से मैं सी ++ से संपर्क करना चाहता था। 'Ptr_vector' की आंतरिक कार्यप्रणाली दिखाने के लिए – polyclick

उत्तर

5

नहीं, यह एक रिसाव नहीं बनाता है। सभी ptr_* कंटेनर उन वस्तुओं को हटा देंगे जो कंटेनर गुंजाइश से बाहर हो जाते हैं।

यदि आप इसे कंटेनर में जोड़ने के बाद ऑब्जेक्ट को हटाते हैं, तो आप undefined behavior बनाएंगे क्योंकि कंटेनर इसे फिर से हटाने का प्रयास करेगा।

अतिरिक्त प्रश्न: नहीं, यदि आप मूल्य के अनुसार ptr_vector स्टोर करते हैं तो इसके जीवनकाल को आसपास के वर्ग के दायरे से प्रबंधित किया जाता है।

चलो ptr_vector का एक सरल कार्यान्वयन लिखें। अप्रत्यक्ष iterators और कस्टम deleters और कई अन्य चीजों के लिए इसका कोई समर्थन नहीं है, लेकिन इस्तेमाल सिद्धांतों को दिखाता है।

template <typename T> 
class ptr_vector { 
public: 
    // assume control over it 
    void push_back(T* x) 
    { if(x) c_.push_back(x); else throw bad_pointer(); } 

    ~ptr_vector() { 
    // delete everything that is stored here 
    for(auto x : c_) delete x; 
    } 
private: 
    std::vector<T*> c_; 
}; 


// a user class 
struct user_class { 
    void addSomething() { x.push_back(new int(23)); } 
    ptr_vector<int> x; 
}; 

उपयोगकर्ता वर्ग क्षेत्र से बाहर चला जाता है, ptr_vector का नाशक कहा जा जाएगा और सभी स्मृति पुनः दावा किया जाएगा। दृष्टि में कोई रिसाव नहीं।

+0

+1;) – polyclick

0

ptr_vector अपने तत्वों में सभी तत्वों को मुक्त कर देगा, इसलिए आपको पहले से किए गए कार्यों से अधिक कुछ करने की ज़रूरत नहीं है, यानी, वस्तुओं को बनाएं, उन्हें ptr_vector पर जोड़ें, और प्रबंधन को छोड़ दें। कॉलिंग delete स्पष्ट रूप से ऑब्जेक्ट को दो बार नष्ट कर देगा (एक बार जब आप इसे अनुरोध करते हैं और फिर ptr_vector समाप्त होता है)। दूसरे शब्दों में, ptr_vector ऑब्जेक्ट को डुप्लिकेट नहीं करता है।

जब ApplicationEngine समाप्त होता है, यदि इसमें ptr_vector का उदाहरण है, तो उस वेक्टर के विनाशक को बुलाया जाएगा, जो बदले में अतिरिक्त वस्तुओं को हटा देता है।

2
void push_back(T* x); 

आवश्यकताएँ:! X = 0 प्रभाव: कंटेनर में सूचक सम्मिलित करता है और यह के स्वामित्व फेंकता लेता है: bad_pointer अगर एक्स == 0 अपवाद सुरक्षा: मजबूत गारंटी

template 
    < 
     class T, 
     class CloneAllocator = heap_clone_allocator, 
     class Allocator  = std::allocator<void*> 
    > 
    class ptr_vector : public ptr_sequence_adapter 
           < 
            T, 
            std::vector<void*,Allocator>, 
            CloneAllocator 
           > 

तो आप अपना खुद का CloneAllocator निर्दिष्ट कर सकते हैं और ptr_vector में संग्रहीत तत्वों को हटा नहीं सकते हैं, लेकिन heap_clone_allocator (CloneAllocator के लिए डिफ़ॉल्ट पैरा) विनाशक में सभी संग्रहीत तत्वों को हटा देता है।

http://www.boost.org/doc/libs/1_50_0/libs/ptr_container/doc/reference.html#class-heap-clone-allocator

संबंधित मुद्दे