2012-04-30 13 views
5

मैंने यह छोटा कोड लिखा है कि यह देखने के लिए कि वास्तव में एक इटरेटर वास्तव में कैसे अमान्य हो जाता है और इसकी क्षमता के बाद वेक्टर के बदले स्थान को इंगित नहीं करता है।क्षमता के पहुंचने के बाद वेक्टर में सम्मिलन कब किया जाता है जब सी ++ इटरेटर का ख्याल नहीं रखता है?

यहां वेक्टर और क्षमता का आकार प्रारंभ में 5 है। इसके बाद मैंने वेक्टर में कुछ अन्य तत्व डाले और myvector.begin() पर इंगित करने के लिए मेरे इटरेटर को दोबारा शुरू नहीं किया। यह के बाद मेरे आउटपुट में 49 के जंक वैल्यू का कारण बनता है जब वेक्टर के तत्वों को फिर से प्रिंट करते हैं।

मेरा सवाल यह है कि सी ++ सभी तत्वों को नए स्थान पर कॉपी करने के बाद एक वैध myvector.begin() पर फिर से इशारा करने वाला नहीं बनाता है?
इससे कुछ व्यवहार भी हो सकते हैं जो डीबग करना मुश्किल हो सकता है। मुझे काम करने का एक सुरक्षित तरीका पता है कि इसे इस्तेमाल करने से पहले हमेशा इटेटरेटर को फिर से शुरू करना होगा।

#include<iostream> 
    #include<vector> 
    #include<stdio.h> 

    using namespace std; 

    int main() 
    { 
    vector<int> myvector; 
    vector<int>::iterator it; 
    int myarray[]= {100,200,300,400}; 
    myvector.insert(it,500); 
    it=myvector.begin(); 
    myvector.insert(it,myarray,myarray+4); 
    it=myvector.begin(); 
    for(;it!=myvector.end();++it) 
    cout <<*it<<endl; 
    cout <<"size of vector is :" << myvector.size() <<"\n"; 
    cout <<"capacity of vector is : " << myvector.capacity()<<"\n"; 
    cout <<"maximum size of vector is : " << myvector.max_size()<<"\n"; 
    myvector.push_back(600); 
    for(;it!=myvector.end();++it) 
    cout <<*it<<endl; 
    } 
    Output of program :- 
    100 
    200 
    300 
    400 
    500 
    size of vector is :5 
    capacity of vector is : 5 
    maximum size of vector is : 1073741823 
    49 
    100 
    200 
    300 
    400 
    500 
    600 
+0

['std :: vector' के साथ जो आकार बदलता है, पिछले इटरेटर को अमान्य करता है] (http://stackoverflow.com/a/6438087/168175) – Flexo

+1

@ वाउडलैंड वह जानता है कि, मुझे लगता है कि वह पूछ रहा है * क्यों * यह हो रहा है। –

+1

प्रत्येक एसटीएल कंटेनर अपने इटरेटर की वैधता के संबंध में कुछ गारंटी देता है। यह समझने का भुगतान करता है कि किसी दिए गए कंटेनर के लिए इटरेटर्स को अमान्य कर दिया जाता है। आप निश्चित रूप से हमेशा एक नए 'शुरू() '' बस 'मामले में रीसेट नहीं करना चाहते हैं। जानकारी पुनः 'वेक्टर' के लिए यहां देखें - http://www.sgi.com/tech/stl/Vector.html –

उत्तर

9

क्योंकि यह अव्यवहारिक और संभवतः असंभव है।

वेक्टर के सभी अपने iterators एक सूची रखने के लिए माना जाता है और उन्हें जैसे ही एक invalide-ट्रिगर विधि कहा जाता है उन सभी को संशोधित?

+0

एक स्थान आवंटित किया जा सकता है जिसमें myvector.begin() का पता होता है और सभी इटरेटर उस स्थान पर इंगित करते हैं और फिर वहां से मूल पते या वेक्टर की प्रारंभिक स्थिति से।और वेक्टर के घूरने वाले स्थान को रखने वाले इस पते को वेक्टर के लिए आवंटित नई जगह के रूप में संशोधित किया जा सकता है? क्या यह बहुत अधिक ऊपरी होगा? मैं उस विशेषज्ञ से नहीं पूछ रहा हूं। – Invictus

+1

@Ritesh यदि आपके पास इटरेटर लोड हैं तो यह किसी विशेष लाभ के लिए बहुत अधिक ओवरहेड होगा। यह सिर्फ शुरू और अंत नहीं है, आपको याद है, और यह जरूरी नहीं है कि प्रत्येक में से केवल एक। –

+1

@ रितेश - आप हमेशा इटरेटर के साथ एक कंटेनर बना सकते हैं जो ऐसा करता है, लेकिन यह देखते हुए कि 'std :: list' मौजूद है, जो बढ़ता है जब यह बढ़ता नहीं है, यह उचित नहीं लगता है। – Flexo

3

संभवतः क्योंकि वेक्टर को अपने सभी पुनरावृत्तियों की सूची का ट्रैक रखना होगा और जब वे अमान्य हो जाएंगे तो उन्हें सूचित करें। यह बल्कि बहुत अधिक ओवरहेड पेश करेगा। एसटीएल कंटेनर के संचालन में सभी के पास बहुत अच्छी तरह से निर्दिष्ट अमान्यता नियम हैं, आपको केवल प्रोग्रामर के रूप में उनका पालन करना होगा।

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

4

इटरेटर किसी भी सार्थक तरीके से वेक्टर से बंधे नहीं है (अगर यह सूचक था तो इसे कैसे लागू किया जा सकता है?)। वेक्टर इटरेटर के बारे में नहीं जानता है। अमान्य इटरेटर का उपयोग न करना आपका काम है।

तो आप वेक्टर कक्षा में जटिलता का एक टन जोड़ने का प्रस्ताव ... किस उद्देश्य के लिए वास्तव में? यह वास्तविक दुनिया में समस्याएं कैसे हल करता है जहां हम जानते हैं कि ऐसी चीज करना एक बुरा विचार है?

1

एसटीएल सभी संभावित कंटेनरों को लागू करने की कोशिश नहीं करता था। जबकि आपका कंटेनर डिज़ाइन निश्चित रूप से संभव है, यह अभी शामिल नहीं है। std::vector<T> समान लगता है, लेकिन यह T[] से थोड़ा अधिक ओवरहेड के साथ एक बेहतर सरणी होने का प्रयास करता है। वह लक्ष्य आपके साथ सीधे संगत नहीं है।

सौभाग्य से, एसटीएल डिज़ाइन मॉड्यूलर है, इसलिए यदि आपने इस तरह के कार्य करने के लिए अपना स्वयं का कंटेनर लिखा है, तो भी आप सभी एसटीएल एल्गोरिदम, साथ ही एसटीएल-संगत एल्गोरिदम (जैसे बूस्ट में) का पुन: उपयोग कर सकते हैं।