2009-10-28 20 views
10

में मिटाएं() कॉल के बाद std :: set में कॉल मिटाएं इटरेटर को अमान्य करें? जैसा कि मैंने पिछली पंक्ति से 5 वें स्थान पर किया है ..? यदि हाँ सेट से सभी तत्वों को मिटाने के लिए बेहतर तरीका क्या हैइटरेटर वैधता, std :: set

class classA 
{ 
public: 
    classA(){}; 
    ~classA(){}; 
}; 
struct structB 
{ 
}; 

typedef std::set <classA*, structB> SETTYPE;   
typedef std::map <int, SETTYPE>MAPTYPE; 

int __cdecl wmain (int argc, wchar_t* pArgs[]) 
{ 
    MAPTYPE mapObj; 
    /* 
     ... 
     .. Some Operation Here 
     ... 
     */ 
    for (MAPTYPE::iterator itr1=mapObj.begin(); itr1!=mapObj.end(); itr1++) 
    {  
     SETTYPE li=(*itr1).second; 
     for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++) 
     { 
      classA *lt=(classA*)(*itr2); 
      li.erase(itr2); 
      delete lt; // Does it invalidate Iterator ? 
     } 
    } 
} 
+2

टाइपपीफ std :: set SETTYPE; मुझे यकीन नहीं है कि आप स्ट्रक्चरब को std :: सेट पर दूसरे टेम्पलेट तर्क के रूप में क्यों दे रहे हैं। std :: set केवल एक मान रखता है (मानचित्र के साथ सेट के साथ कोई कुंजियां नहीं हैं), दूसरा टेम्पलेट तर्क सेट के लिए तुलनात्मक फ़ैक्टर प्रदान करने के लिए उपयोग किया जाता है (डिफ़ॉल्ट रूप से std :: कम) –

उत्तर

2

जब से तुम सिर्फ जाहिरा तौर पर सेट के प्रत्येक तत्व हटा रहे हैं, तो आप सिर्फ कर सकता है:

for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();itr2++) 
    { 
      classA *lt=(classA*)(*itr2); 
      delete lt; 
    } 
    li.clear(); // clear the elements 
+0

thx reko_t, यह मेरा हल करता है समस्या – Satbir

41
मानक 23.1.2

से

सम्मिलित सदस्य कंटेनर की पहचानकर्ताओं और संदर्भों की वैधता को प्रभावित नहीं करेंगे, और मिटाए गए सदस्यों को केवल तत्वों और मिटाए गए तत्वों के संदर्भों को अमान्य कर दिया जाएगा।

संपादित

आपके मामले में itr2 तो मिटा incrementing यह अनिर्धारित व्यवहार का कारण बनता है के बाद अवैध है। इस मामले आप reko_t सलाह, सामान्य रूप में पालन कर सकते हैं, आप इस कोशिश कर सकते हैं:

for (SETTYPE::iterator itr2=li.begin();itr2!=li.end();) 
{ 
    classA *lt=(classA*)(*itr2); 
    li.erase(itr2++); 
    delete lt; 
} 

जो दूर करने में यह सेट से पिछले मान है से पहले इटरेटर बढ़ेगी, जब।
बीटीडब्ल्यू। itr2 को delete lt; द्वारा अमान्य नहीं किया गया है, लेकिन li.erase(itr2);

+3

चूंकि यह मेरा Google का जवाब देता है "सेट इटेटेटर अमान्य मिटा देता है", यह मेरा पसंदीदा उत्तर – Chance

+0

मेरा पसंदीदा उत्तर भी है! – Micka

7

हटाएं ठीक है।

समस्या यह है कि आप मिटाते हैं - और इस प्रकार अमान्य - itr2, लेकिन इसे लूप पुनरावृत्ति के लिए उपयोग करें।

i.a.w. पहले मिटाए जाने के बाद, ++itr2 ने परिणामों को अपरिभाषित किया है।

पैटर्न मैं इस स्थिति में उपयोग यह है:

while(itr2 != end()) 
{ 
    iterator toDelete = itr2; 
    ++itr2; // increment before erasing! 
    container.erase(toDelete); 
} 

कुछ अमानक एसटीएल impls है अगले इटरेटर लौट मिटा है, तो आप कर सकता है:

while(itr2 != end()) 
    itr2 = container.erase(); 

कि पोर्टेबल नहीं है, हालांकि।


set<A*,B> अजीब है, हालांकि है - एक मानक impl में, बी तुलनित्र होगा।

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