2015-01-22 2 views
10

यदि मेरे पास कंटेनर है और clear() पर कॉल करें, तो क्या केवल अंदर मौजूद सभी तत्वों को नष्ट कर देता है या वास्तव में यह आंतरिक रूप से नई स्मृति आवंटित/आवंटित करता है? क्या यह व्यवहार सी ++ मानक के दायरे से बाहर है? ideone (http://ideone.com/XQi8IT) पर एक त्वरित परीक्षणकंटेनर.क्लियर() मुक्त/आंतरिक बफर को पुन: आवंटित करता है?

unordered_set<int> mySet { 1, 2, 3, 4, 5 }; 
mySet.reserve(1000); 
mySet.clear(); 

//Is this pointless/redundant 
//or should I treat my container like it was just constructed? 
mySet.reserve(1000); 

पता चलता है कि के बाद एक कॉल स्पष्ट करने के लिए आंतरिक स्मृति बफर बनाए रखा है:

यह करने के लिए निर्भर करता है। तो, कम से कम unordered_set पर g ++ के नए संस्करणों के लिए यह मामला है। मेरा सवाल 1 पर जाता है) मानक क्या कहता है, अगर कुछ और 2) क्या यह व्यवहार सभी कंटेनरों में सुसंगत है।

+3

यह निर्दिष्ट नहीं है। Http://www.cplusplus.com/reference/vector/vector/clear/ देखें। इसलिए (वैक्टरों के लिए), आप shrink_to_fit –

+0

@ साइबर का उपयोग कर सकते हैं - 'आकार बदलें' विधि 'unordered_set' और अन्य कंटेनर पर लागू नहीं होती है। यह सवाल अधिक सामान्य है, यह कुछ अलग पूछ रहा है। हालांकि दिलचस्प पढ़ा - धन्यवाद। – Mark

+2

@ मार्क यह कंटेनर पर निर्भर करता है - उदाहरण के लिए, 'std :: map' जैसे पेड़ संरचनाओं में क्षमता नहीं है। जब आप पेड़ से एक मूल्य हटाते हैं, तो उस नोड को तुरंत नष्ट कर दिया जाता है और इसलिए 'साफ़() 'आवंटित सभी आंतरिक आवंटित मुक्त हो जाएगा। – cdhowie

उत्तर

13

यह स्मृति के साथ क्या होता है इसके बारे में अनिश्चित है। यह सिर्फ परिभाषित करता है निम्न आवश्यकताओं:

अनुक्रम कंटेनरों के लिए हम है clear() के लिए निम्न आवश्यकताओं:

[C++11 §23.2.3] टेबल 100

a में सभी तत्वों को नष्ट कर देता है। सभी संदर्भों को इंगित करता है, पॉइंटर्स, और इटरेटर a के तत्वों का जिक्र करते हैं और अतीत-अंत-अंतरालकर्ता को अमान्य कर सकते हैं।

पोस्ट: a.empty() रिटर्न true

कौन वास्तव में स्मृति के बारे में कुछ भी उल्लेख नहीं है।

[C++11 §23.2.4] टेबल 102

a.erase(a.begin(),a.end())

कौन सा erase(...) आवश्यकताओं जो कर रहे हैं की ओर जाता है:

मिटा देता है तत्व द्वारा की ओर इशारा सहयोगी कंटेनरों के लिए हम clear() के लिए इस आवश्यकता है q। तत्व मिटाए जाने से पहले q के तुरंत बाद तत्व को इंगित करने वाला एक पुनरावर्तक देता है। यदि कोई ऐसा तत्व मौजूद नहीं है, तो a.end()

जो फिर से कंटेनर के मेमोरी बफर की क्षमता के बारे में कुछ भी नहीं बताता है।

[C++11 §23.2.5] टेबल 103

कंटेनर में सभी तत्वों को मिटाता है: तो फिर हम जो समान शब्दों है सहयोगी कंटेनर अव्यवस्थित है। पोस्ट: a.empty() रिटर्न true

कुल मिलाकर, मानक कुछ भी उल्लेख नहीं है clear के बाद आंतरिक स्मृति बफ़र्स होता है। तो यह अनिर्दिष्ट व्यवहार है जो विभिन्न कार्यान्वयन के बीच भिन्न हो सकता है।

reserve के बाद से (जो क्षमता को बदलने करता है) और न दूसरी सबसे बड़ी चीज (shrink_to_fit) वहाँ एक अच्छा तरीका लगातार बाहर एक कंटेनर की आंतरिक स्मृति स्पष्ट करने के लिए प्रतीत नहीं होता है सभी कंटेनर में उपलब्ध नहीं है।

+1

उपरोक्त। libC++ और libstdC++ 'clear()' भर में 'bucket_count()' को सुरक्षित रखें। वीएस -2015 नहीं है। –

3

किसी भी मानक कंटेनर के लिए किसी भी स्मृति को मुक्त करने के लिए सी ++ मानक में कोई आवश्यकता नहीं है। यहां तक ​​कि समारोह std::vector<T>::shrink_to_fit() केवल स्मृति की सिकुड़ने का अनुरोध करता है। इस समारोह की तरह

std::vector<T>().swap(myVector); 

मुहावरे को बदलने के लिए यह मुहावरा वास्तव में मुक्त स्मृति है, जो std::vector<T>::clear() द्वारा इसकी गारंटी नहीं है करने के लिए इस्तेमाल किया गया था सोचा है। (वास्तव में, std::vector<T>::clear() को capacity() अपरिवर्तित छोड़ने के लिए निर्दिष्ट किया गया है।) आप अभी भी अन्य कंटेनरों के लिए इस मुहावरे का उपयोग कर सकते हैं, जिनके पास shrink_to_fit() कोई फ़ंक्शन नहीं है।

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