2013-02-01 27 views
10

चेक इस कोड:क्या std :: list :: clear std :: list :: end iterator को साफ़ करें?

#include "stdafx.h" 
#include <list> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::list<int> mylist; 
    mylist.push_back(1); 
    std::list<int>::iterator i = mylist.end(); 
    if(i == mylist.end()) 
     printf("end is end\n"); 

    mylist.clear(); 
    if(i == mylist.end()) 
     printf("never get here because Microsoft seems to " 
       "think the iterator is no longer safe.\n"); 

    return 0; 
} 

अब, cplusplus.com के अनुसार यह एक समस्या नहीं होनी चाहिए, और रिलीज़ मोड में, मुझे लगता है कि यह ठीक है और वास्तव में किसी भी मुद्दे का कारण नहीं है, लेकिन डिबगिंग के रूप में असंभव हो जाता है यह मुझे जारी रखने के बिना बस बेल्स। कोई संकेतक?

+0

दिलचस्प। मैंने सोचा था कि '.end' भी अमान्य है, लेकिन लेख विपरीत कहता है। यह दिलचस्प है कि http://ideone.com/Y338N8 इसे अपेक्षित रूप से निष्पादित करता है। +1 –

+0

यह सही समझ में आता है क्योंकि जिस कोड को मैं विंडोज़ को पोर्ट करने की कोशिश कर रहा हूं उसे मैकोज़ और लिनक्स को लक्षित किया गया था। दोनों जीसीसी चल रहे हैं, जैसा कि विचार करता है। मुझे लगता है कि यह एक पुस्तकालय बग है। –

उत्तर

10

अन्य उत्तरों बताते हैं कि, सामान्य रूप से, आप कंटेनर को साफ़ होने पर मान्य कंटेनर के पिछले-एंड-एंडरेटर पर भरोसा नहीं कर सकते हैं। हालांकि, एक सूची के पास्ट अंत इटरेटर वास्तव में वैध रहना चाहिए:

सी ++ 11 23.3.5.4/3 प्रभाव: को अमान्य कर केवल iterators और मिट तत्वों के लिए संदर्भ।

पिछले-एंड-एंडरेटर किसी भी तत्व का संदर्भ नहीं देता है, इसलिए इसे अमान्य नहीं किया जाना चाहिए।

+0

+1, मेरा जवाब हटा दिया। जबकि मुझे पिछली बातचीत से याद है कि गतिशील रूप से आवंटित प्रेषण का उपयोग मानक द्वारा स्पष्ट रूप से समर्थित है, इसका मतलब यह नहीं है कि 'स्पष्ट()' इसे रिलीज़ करने की आवश्यकता है। हमारे कार्यान्वयन को दो बार चेक किया गया है और 'साफ़() 'को मिटाने (प्रारंभ(), अंत()) के रूप में कार्यान्वित किया गया है और' end() 'iterators को अमान्य नहीं करता है। यह माइक्रोसॉफ्ट को उनके कार्यान्वयन में एक बग के रूप में सूचित किया जाना चाहिए। –

+2

धन्यवाद, माइक और @ डेविड रोडिगुएज़-ड्राईबीस। हां, यह विजुअल सी ++ 2012 'std :: list' कार्यान्वयन में एक बग है। यह विजुअल सी ++ 2010 से एक प्रतिगमन है। ध्यान दें कि 'मिटाएं' समान रूप से टूटा हुआ है। मैंने कुछ महीने पहले इस बग के लिए एक फिक्स में चेक किया था, और फिक्स विजुअल सी ++ मानक लाइब्रेरी के अगले रिलीज़ संस्करण में दिखाई देगा। फिक्स 'मिटाएं' और 'स्पष्ट' दोनों को ठीक करता है। (यह बग एक ग्राहक द्वारा रिपोर्ट किया गया था, लेकिन माइक्रोसॉफ्ट कनेक्ट के माध्यम से नहीं, इसलिए मेरे पास कोई लिंक नहीं है जिसके लिए मैं आपको संदर्भित कर सकता हूं।) –

+1

माइक्रोसॉफ्ट को रिपोर्ट किया गया, निश्चित लेकिन केवल वीएस2013 में: http://connect.microsoft। com/VisualStudio/प्रतिक्रिया/विवरण/808,659/एसटीडी-सूची-टी मिटा में डिबग मोड-अमान्य कर देता है अंत-इटरेटर – Macker

-2

यह वास्तव में अमान्य है। इटरेटर केवल वर्तमान राज्य कंटेनर पर मान्य हैं। आइटम जोड़ने या निकालने के बाद, इटेटरेटर अब मान्य नहीं है।

आपके द्वारा लिंक किया गया लेख यह नहीं कहता कि आप क्या कर रहे हैं वह मान्य है। स्पष्ट होने के बाद उन्हें एक नया इटरेटर मिल जाता है।

रिलीज कोड में दिखाई देने का कारण यह नहीं है क्योंकि इस समस्या को उठाते हुए डिबगिंग अक्षम है।

+0

और एक और बार: प्रश्न में दिए गए लिंक के मुताबिक: "इस कंटेनर से संबंधित सभी इटरेटर, संदर्भ और पॉइंटर्स को अंतिम इटरेटर को छोड़कर अमान्य कर दिया गया है।" –

+0

@meh: नहीं, आप गलत हैं, एंड इटरेटर * को –

+3

अमान्य किया जा सकता है "एक बार जब आप आइटम जोड़ते या निकालते हैं, तो इटेटरेटर अब मान्य नहीं है।" यह सामान्य में सच नहीं है; प्रत्येक कंटेनर के अपने स्वयं के अमान्यता नियम होते हैं, और 'सूची' इटरेटर तब तक वैध रहते हैं जब तक वे जो तत्व संदर्भित करते हैं वह अभी भी एक सूची में है। –

4

से सी ++ 11, टेबल 100 (अनुक्रम कंटेनर आवश्यकताओं):

clear() [...] पास्ट अंत इटरेटर अमान्य हो सकती है।

और std::list निश्चित रूप से एक दृश्य कंटेनर टेम्पलेट (23.3.5.1/2) है:

सूची एक कंटेनर की आवश्यकताओं, एक प्रतिवर्ती कंटेनर के के सभी को संतुष्ट करता है (में दो तालिकाओं में दी गई 23.2), अनुक्रम कंटेनर, जिसमें वैकल्पिक अनुक्रम कंटेनर आवश्यकताओं (23.2.3), और आवंटक-जागरूक कंटेनर (तालिका 99) शामिल हैं। अपवाद ऑपरेटर [] और सदस्य कार्यों पर हैं, जो प्रदान नहीं किए जाते हैं। विवरण केवल उन सूचीओं पर संचालन के लिए प्रदान किए जाते हैं जिन्हें इन तालिकाओं में से किसी एक में वर्णित नहीं किया गया है या उन परिचालनों के लिए जहां अतिरिक्त अर्थपूर्ण जानकारी है।

+0

इसमें जोड़ने के लिए: 'end' iterator एकवचन मूल्य है और अधिकांश नोड बेस कंटेनर जो इटरेटर की स्थिरता की गारंटी देते हैं, केवल गैर-एकवचन मूल्यों के लिए यह गारंटी देते हैं। –

+1

मेरा मानना ​​है कि इसे पढ़ा जाना चाहिए "ऐसे कंटेनर हैं जिनके लिए यह अतीत-अंत-अंतराल और कंटेनर को अमान्य करता है जिसके लिए यह नहीं है"। अन्यथा, यह एक विरोधाभासी विनिर्देश होगा –

+1

लेकिन सूची-विशिष्ट विनिर्देश, 23.3.5.4/3, कहता है "केवल अमान्य ** ** ** मिटाए गए तत्वों के संकेतक और संदर्भ।" –