2012-10-09 14 views
17

मान लें मैं इस तरह एक वर्ग को परिभाषित किया है:संकेत का एक वेक्टर समाशोधन

class foo { 
private: 
    std::vector< int* > v; 
public: 
    ... 
    void bar1() 
    { 
     for (int i = 0; i < 10; i++) { 
     int *a = new int; 
     v.push_back(a); 
     } 
    }; 

    void bar2() 
    { 
     std::vector<int>::iterator it = v.begin(); 
     for (; it != v.end(); it++) 
     std::cout << (*it); 
     v.clear(); 
    } 
}; 

संक्षेप में, मैं एक सदिश में कुछ संकेत दिए गए पीछे धकेलने, बाद में मैं वेक्टर साफ़ करें। सवाल यह है कि क्या इस कोड में स्मृति रिसाव है? मेरा मतलब है वेक्टर को साफ़ करके, क्या पॉइंटर्स ठीक से हटाए गए हैं?

+2

आप वास्तव में वेक्टर के लिए केवल एक ही सूचक धक्का; 'bar1' में 'for' लूप' केवल 'नई int;' लाइन निष्पादित करता है क्योंकि इसमें कोई घुंघराले ब्रेसिज़ नहीं है, और 'i +++' एक वाक्यविन्यास त्रुटि है और ... आह ठीक है, मुझे लगता है कि यह छद्म कोड होना है। –

+0

@ फ्रीरिक राबे: संपादित ... – mahmood

+0

आपको इंट पॉइंटर्स के वेक्टर की भी आवश्यकता है: 'std :: vector < int* > v;' 'std :: vector < int > v;' – juanchopanza

उत्तर

24

हां, कोड मेमोरी लीक है जब तक आप पॉइंटर्स को हटा नहीं देते। यदि foo कक्षा पॉइंटर्स का मालिक है, तो उन्हें हटाना उनकी ज़िम्मेदारी है। आपको वेक्टर को साफ़ करने से पहले ऐसा करना चाहिए, अन्यथा आप उस स्मृति को हैंडल खो देते हैं जिसे आपको हटाने की आवश्यकता है।

for (std::vector<int>::iterator it = v.begin() ; it != v.end(); ++it) 
    { 
    delete (*it); 
    } 
    v.clear(); 

आपके पास कोई उपयुक्त smart pointer के std::vector का उपयोग करके पूरी तरह स्मृति प्रबंधन समस्या से बचने के सकता है।

+0

क्या आप कृपया मुझे स्ट्रैगिट विधि दे सकते हैं (स्मार्ट पीआरटी नहीं) ?? – mahmood

+0

@ महमूद यह आपकी कक्षा के ब्योरे पर निर्भर करता है, लेकिन यह एक सुरक्षित शर्त है कि आपको वेक्टर को साफ़ करने से ठीक पहले करना चाहिए। प्रत्येक तत्व को हटाने, इसे खत्म करो। * फिर * इसे साफ़ करें। – juanchopanza

+0

@ महमूद मैंने एक उदाहरण जोड़ा। – juanchopanza

6

नहीं, आप केवल वेक्टर स्टोरेज को साफ़ करते हैं। 'नई' के साथ आवंटित स्मृति अभी भी वहां है।

for (int i =0; i< v.size();i++) 
    { 
    delete (v[i]); 
    } 
    v.clear(); 
+0

तो मैं कैसे हटा सकता हूं? – mahmood

+1

प्रत्येक पुनरावृत्ति पर 'हटाएं' का उपयोग करें। वेक्टर को साफ़ करने के लिए स्पष्ट उपयोग के बाद। ई, जी हटाएं (* इसे) –

+0

(ऑटो और i: v) { हटाएं (i); } v.clear(); क्या यह कोड सही है – lsrawat

2

आप for_each उपयोग कर सकते हैं:

std::vector<int*> v; 

template<typename T> 
struct deleter : std::unary_function<const T*, void> 
{ 
    void operator() (const T *ptr) const 
    { 
    delete ptr; 
    } 
}; 

// call deleter for each element , freeing them 
std::for_each (v.begin(), v.end(), deleter<int>()); 
v.clear(); 
+0

मुझे अक्सर ऐसा लगता है कि इस 'डिलीटर' को आसानी से उपलब्ध किया गया हो; मुझे आश्चर्य है, क्या आप इसे 'std :: mem_fun_ptr या' std: fun_ptr' के संदर्भ में कार्यान्वित कर सकते हैं? –

6

मुझे लगता है कि कम से कम और स्पष्ट समाधान होगा:

std::vector<Object*> container = ... ; 
for (Object* obj : container) 
    delete obj; 
container.clear();