2010-04-28 10 views
6

मैं परिभाषित करनेएसटीएल इटरेटर डीबगिंग को वास्तव में क्या करने में सक्षम बनाता है?

_HAS_ITERATOR_DEBUGGING = 1 

मैं उम्मीद कर रहा था यह वास्तव में सिर्फ वेक्टर सीमा की जाँच करने के द्वारा एक आवेदन में इटरेटर डिबगिंग सक्रिय कर दिया है, लेकिन मैं एक महसूस कर रही है कि यह एक बहुत है कि अधिक से अधिक कर रहा है। वास्तव में क्या चेक, आदि प्रदर्शन किया जा रहा है?

डंकमवेयर एसटीएल, वैसे भी।

+1

एक तरफ ध्यान दें पर, मुझे आश्चर्य है कि कितने लोगों को वास्तव में पता है कि Dinkumware एसटीएल :) – sbk

+0

है तुम नहीं जानते, तो आप शायद इस सवाल का जवाब नहीं कर सकते हैं :-) – Roddy

उत्तर

7

iterators जो अपरिभाषित व्यवहार करने के लिए नेतृत्व के साथ संचालन की एक संख्या है, इस ट्रिगर के लक्ष्य यह घटित होने से बचाने के क्रम चेकों को सक्रिय करने के (का उपयोग करते हुए इस बात पर ज़ोर) है।

मुद्दा

स्पष्ट आपरेशन गलत iterator उपयोग करने के लिए है, लेकिन इस अमान्यता विभिन्न कारणों से उत्पन्न हो सकती:

  • Unitialized इटरेटर
  • एक तत्व है कि मिटा दिया गया है करने के लिए इटरेटर
  • भौतिक स्थान बदलने वाले तत्व के लिए इटरेटर (vector के लिए पुनर्वितरण)

प्रत्येक कंटेनर जो आपरेशन को अमान्य कर जो इटरेटर के लिए कष्टदायी विवरण में मानक सटीक के बाहर 10

  • इटरेटर।

    वहाँ एक किसी भी तरह कम स्पष्ट कारण यह है कि लोग भूल जाते हैं के लिए करते हैं है: विभिन्न कंटेनरों को iterators मिश्रण:

    std::vector<Animal> cats, dogs; 
    
    for_each(cats.begin(), dogs.end(), /**/); // obvious bug 
    

    यह एक अधिक सामान्य मुद्दे से संबंधित: पर्वतमाला एल्गोरिदम के लिए पारित की वैधता।

    • [cats.begin(), dogs.end()) अमान्य है
    • [cats.end(), cats.begin()) अमान्य है (जब तक cats खाली है ??)

    समाधान

    समाधान होते हैं (जब तक कि एक दूसरे के लिए एक उपनाम है) इटरेटर को जानकारी जोड़ने में ताकि उनकी वैधता और परिभाषित श्रेणियों की वैधता निष्पादन के दौरान ज़ोर दी जा सके, इस प्रकार अपरिभाषित को रोकें व्यवहार होने के लिए।

    _HAS_ITERATOR_DEBUGGING प्रतीक इस क्षमता के लिए एक ट्रिगर के रूप में कार्य करता है, क्योंकि दुर्भाग्य से यह प्रोग्राम धीमा हो जाता है। सिद्धांत में यह काफी सरल है: प्रत्येक इटरेटर को Observer बनाया गया कंटेनर बनाया गया है और इस प्रकार इसे संशोधित किया गया है।

    Dinkumware में यह दो अतिरिक्त द्वारा हासिल की है:

    • प्रत्येक इटरेटर इससे संबंधित कंटेनर के लिए एक सूचक किया जाता है
    • प्रत्येक कंटेनर यह बनाया

    iterators और यह की एक लिंक्ड सूची रखती है अच्छी तरह से हमारी समस्याओं को हल करता है:

    • एक प्रारंभिक इटरेटर में कोई नहीं है पैरेंट कंटेनर, सबसे परिचालन (अलग काम और विनाश से) ट्रिगर किया जाएगा एक अभिकथन
    • एक मिट या स्थानांतरित तत्व के लिए एक iterator (सूची के लिए धन्यवाद) अधिसूचित किया गया है और इसके अमान्यता
    • के बारे में पता incrementing और पुनरावर्तक decrementing पर यह जांच कर सकता है कि यह सीमा
    • जांच कर रहा है कि 2 पुनरावर्तक एक ही कंटेनर से संबंधित हैं, उनके माता-पिता पॉइंटर्स की तुलना में उतना आसान है
    • किसी सीमा की वैधता की जांच करना उतना आसान है जितना कि हम सीमा के अंत तक पहुंचते हैं इससे पहले कि हम कंटेनर के अंत तक पहुंचें (उन कंटेनर के लिए रैखिक ऑपरेशन जो यादृच्छिक रूप से सुलभ नहीं हैं, इस प्रकार उनमें से अधिकतर)

    लागत

    लागत भारी है, लेकिन शुद्धता है एक कीमत है? परिवर्तनशील कार्यों पर O(NbIterators)

  • सूचना प्रक्रिया:

    • अतिरिक्त स्मृति आवंटन (बनाए रखा iterators की अतिरिक्त सूची): हम लागत हालांकि बंद कर सकता है O(NbIterators) (ध्यान दें कि push_back या insert करना जरूरी नहीं कि iterators को अमान्य कर, लेकिन erase करता है)
    • रेंज वैधता की जांच: O(min(last-first, container.end()-first))

    पुस्तकालय एल्गोरिदम के अधिकांश निश्चित रूप से लागू किया गया है च या अधिकतम दक्षता, आम तौर पर चेक एक बार और एल्गोरिदम की शुरुआत में किया जाता है, फिर एक अनचेक संस्करण चलाया जाता है।फिर भी गति गंभीर रूप से, धीमा हो सकता है विशेष रूप से हाथ से लिखा छोरों के साथ:

    for (iterator_t it = vec.begin(); 
        it != vec.end();    // Oups 
        ++it) 
    // body 
    

    हम जानते हैं Oups लाइन खराब स्वाद है, लेकिन यहाँ तो यह और भी बदतर है: पाश के प्रत्येक रन पर, हम एक नया बनाने इटरेटर तो इसे नष्ट आवंटन और iterators की vec की सूची के लिए एक नोड deallocating जिसका मतलब है ... मैं आवंटन/एक तंग पाश में स्मृति deallocating की लागत को रेखांकित किया है?

    बेशक, for_each ऐसी समस्या का सामना नहीं करेगा, जो हाथ से कोडित संस्करणों के बजाय एसटीएल एल्गोरिदम के उपयोग की ओर एक और आकर्षक मामला है।

  • 0

    जहां तक ​​मैं समझता हूँ:

    _HAS_ITERATOR_DEBUGGING रन टाइम पर एक संवाद बॉक्स प्रदर्शित सहित किसी भी गलत iterator उपयोग पर जोर देने होंगे:

    1) एक तत्व के बाद एक कंटेनर में इस्तेमाल Iterators मिटा दिया जाता है

    2) एक .push के बाद वैक्टर में इस्तेमाल Iterators() या .Insert() फ़ंक्शन

    0

    कहा जाता है http://msdn.microsoft.com/en-us/library/aa985982%28v=VS.80%29.aspx

    के अनुसार

    सी ++ मानक वर्णन करता है कि कौन से सदस्य फ़ंक्शन इटरेटर को कंटेनर को अमान्य बनने का कारण बनते हैं। दो उदाहरण हैं:

    • एक कंटेनर से एक तत्व मिटाया जा रहा है का कारण बनता है तत्व को iterators अमान्य हो गया है।
    • वेक्टर (पुश या डालने) के आकार को बढ़ाने से वेक्टर कंटेनर में इटरेटर अमान्य हो जाते हैं।
    संबंधित मुद्दे