c++ - समझ - वीएस, यूनिक्स/लिनक्स में इसे मिटाकर एक एसटीएल इटरेटर के साथ क्या होता है?




हिन्दी में लिनक्स बूटिंग प्रक्रिया (3)

कृपया निम्न परिदृश्य पर विचार करें:


map(T,S*) & GetMap(); //Forward decleration

map(T, S*) T2pS = GetMap();

for(map(T, S*)::iterator it = T2pS.begin(); it != T2pS.end(); ++it)
{
    if(it->second != NULL)
    {
        delete it->second;
        it->second = NULL;
    }
    T2pS.erase(it);
    //In VS2005, after the erase, we will crash on the ++it of the for loop.
    //In UNIX, Linux, this doesn't crash.
}//for

मुझे ऐसा लगता है कि वीएस 2005 में "मिटाने" के बाद, इटरेटर अंत के बराबर होगा, इसलिए इसे बढ़ने की कोशिश करते समय क्रैश होता है। क्या यहां वास्तव में प्रस्तुत किए गए व्यवहार में कंपाइलर्स के बीच अंतर है? यदि हां, तो यूनिक्स / लिनक्स में "मिट" के बराबर इटरेटर क्या होगा?

धन्यवाद...


एक इटरेक्टर पर एक std::map में erase देने के बाद, यह अमान्य है इसका मतलब यह है कि आप इसका उपयोग नहीं कर सकते। इसे प्रयोग करने का प्रयास करना (उदाहरण के लिए इसे बढ़ाना) अमान्य है और कुछ भी हो सकता है (क्रैश सहित) एक std::map , एक इटरेटर पर erase पर कॉल करने से किसी अन्य इटरेटर को इस कॉल के बाद (उदाहरण के लिए) अमान्य नहीं होता है, (जब तक it T2pS.end() नहीं था), यह मान्य होगा:

T2pS.erase( it++ );

बेशक, यदि आप इस दृष्टिकोण का उपयोग करते हैं, तो आप बिना किसी शर्त के लिए लूप में it बढ़ाना चाहते हैं।

इस उदाहरण के लिए, हालांकि, लूप में क्यों मिटाना परेशान है? क्यों न केवल लूप के अंत में T2pS.clear () कॉल करें

दूसरी ओर, ऐसा लगता है कि आपके पास मानचित्र के दाईं ओर एक कच्चा पॉइंटर है, लेकिन मानचित्र को ऑब्जेक्ट की ओर इंगित करने के लिए दिखाई देता है। इस मामले में, क्यों नहीं नक्शे के दाहिनी ओर कुछ प्रकार के स्मार्ट पॉइंटर, जैसे कि std :: tr1 :: shared_ptr?

[संयोग से, मुझे map लिए कोई भी टेम्प्लेट पैरामीटर दिखाई नहीं देता I क्या आपने स्थानीय नामस्थान में std::map रूप में std::map का एक विशिष्ट प्रारंभ किया है?]


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


हां, यदि आप इटरेटर को मिटाते हैं, तो इटरेटर को एक तथाकथित विलक्षण मूल्य मिलता है , जिसका अर्थ है कि यह किसी भी कंटेनर से संबंधित नहीं है। आप इसे बढ़ा नहीं सकते हैं, घटा सकते हैं या इसे पढ़ सकते हैं / लिख सकते हैं। उस पाश का सही तरीका है:

for(map<T, S*>::iterator it = T2pS.begin(); it != T2pS.end(); T2pS.erase(it++)) {
    // wilhelmtell in the comments is right: no need to check for NULL. 
    // delete of a NULL pointer is a no-op.
    if(it->second != NULL) {
        delete it->second;
        it->second = NULL;
    }
}

जब आप एक इटरेटर मिटाते हैं, तो कंटेनरों के लिए अन्य इटेटेटर्स को अमान्य कर सकता है, erase , अगले वैध इरेटरेटर को erase । तो आप इसे साथ करते हैं

it = T2pS.erase(it)

std::deque std::vector और std::deque लिए यह कैसे काम करता है, लेकिन std::map या std::set





map