2015-09-10 10 views
6

मैं समझता हूं कि, जब हम संबंधित new [] द्वारा बनाए गए पॉइंटर पर delete [] लिखते हैं, तो प्रोग्राम सरणी पर लेखांकन जानकारी की तलाश करेगा और सरणी के तत्व आकार (काउंटर) का पता लगाएगा। फिर कार्यक्रम उनमें से प्रत्येक पर तत्व के विनाशक को आमंत्रित करता है। अंत में स्मृति (क्या स्मृति ??) operator delete नामक फ़ंक्शन द्वारा हटा दी गई है।क्या विनाशकों को आह्वान करने के बाद एक शॉट में स्मृति को हटा दिया गया है?

क्या मैं पूछ रहा हूँ कि क्या delete[] पूरे स्मृति, new[] अभिव्यक्ति द्वारा आवंटित पुनःआवंटन जाएगा, एक शॉट में क्योंकि उस जानकारी (स्मृति की कुल राशि) उपलब्ध के बाद सभी तत्वों को नष्ट कर रहे हैं, या होगा यह है क्रमशः सरणी तत्वों द्वारा कब्जा कर लिया गया स्मृति को हटा देता है जिस पर उसने विनाशकों को बुलाया है?

इससे संबंधित एक अनुवर्ती quesion Does delete (non array form) know the total amount of memory allocated by either new or new[]

+2

मैंने सोचा है अपने प्रश्न का उत्तर संकलक और ऑपरेटिंग सिस्टम –

+3

करता है 'free' आवंटन' malloc' द्वारा लौटाए के आकार पता करने की जरूरत द्वारा कार्यान्वयन पर निर्भर करता है? –

+2

क्या सी ++ मानक 'हटाएं' अभिव्यक्ति के अनुमानित व्यवहार के बारे में कुछ भी कहता है? – Rich

उत्तर

2

सभी मेमोरी अंतर्निहित आवंटक को एक बार में जारी की जाएगी। यह सी ++ मानक द्वारा अनिवार्य है, हालांकि विशेष रूप से स्पष्ट रूप से नहीं। N3337 आधिकारिक सी ++ 11 मानक मुफ्त में ऑनलाइन उपलब्ध निकटतम अनुमान है। खंड 5.3.5, [expr.delete] को देखें, जो कोड को बताता है कि delete[] का आविष्कार विस्तारित करता है।विशेष रूप से, operator delete[] चरण 7 में एक बार कहा जाता है, के बाद विनाशकर्ता सरणी (चरण 6) के सभी तत्वों के लिए लागू किया गया है।

आप [new.delete.array] के बारे में क्या संकेत operator delete[] को पारित करने के लिए मान्य हैं 18.6.1.2 में शब्दों से इस व्यवहार को यह मान सकते हैं: "... operator new[] के पहले के एक कॉल द्वारा दिए गए मान होगा (... चेतावनी ...) "। चूंकि operator new[] एक पूरी सरणी के लिए एक सूचक देता है, operator delete[] भी एक पूरी सरणी के लिए एक बार लागू किया जाना चाहिए।

1

5.3.5/2 के लिए कहा जाता है:

पहले विकल्प में (वस्तु हटाना), के संकार्य के मूल्य में एक अशक्त हो सकता है को नष्ट पॉइंटर वैल्यू, एक गैर-सरणी ऑब्जेक्ट पर एक पॉइंटर, जो पिछले ऑब्जेक्ट द्वारा बनाया गया था, या एक उपरोक्त (1.8) के पॉइंटर को ऐसी ऑब्जेक्ट (क्लॉज 10) के बेस क्लास का प्रतिनिधित्व करता है। यदि नहीं, व्यवहार अपरिभाषित है।

यह स्पष्ट रूप से हमें है कि अपने प्रस्तावित स्थिति में व्यवहार मानक है, जो छोड़ देता है "स्मृति लीक नहीं" या "स्मृति लीक" दो सबसे अधिक संभावना अपरिभाषित व्यवहार (ऐसा लगता है कि ढेर भ्रष्टाचार हो सकता है के रूप में से अपरिभाषित है पता चलता पूरी तरह से पूर्णता के लिए तीसरी संभावना की संभावना कम है)। बस इस तरह के कोड मत लिखो और आप संभावित समस्याओं से बचें।

0
अभ्यास अपने उदाहरण

auto pi = new int[10]; 
... 
delete pi; 

काम करता है ठीक काम कर रहा है और कार्यक्रमों में बहुत आम है में

। मैं उन लोगों पर भरोसा रखूंगा जिन्होंने इसे मानक में देखा, यह अपरिभाषित व्यवहार है। तो मैं सुझाव नहीं दूंगा कि आप इस तथ्य का लाभ उठाएं कि यह नियमित रूप से काम करता है। प्रैक्टिस में, आवंटक कुल आकार का ट्रैक रखता है और डेलोकेशन सही कुल आकार को मुक्त करता है, इसलिए नए जोड़ना [] को हटाने के साथ ही शून्य के पिछले तत्वों के विनाशकों को बुलाया जा सकता है और वस्तुओं के सरणी के लिए कोई नुकसान नहीं होता है तुच्छ विनाश लेकिन अपरिभाषित व्यवहार को कोड करना एक अच्छा विचार नहीं है, भले ही आपको विश्वास हो कि हर कंपाइलर उस विशेष यूबी के लिए ठीक व्यवहार करता है।

संपादित करें: अब है कि आप मूल प्रश्न का ही अधिक तुच्छ हिस्सा पूछने के लिए अपने सवाल से सभी को निकाला:

मुझे लगता मानक किसी भी तरह के विस्तार में जाने नहीं है, इसलिए एक कार्यान्वयन या तो कर सकता है। लेकिन मुझे पूरा भरोसा है कि किसी भी वास्तविक कार्यान्वयन ने सभी विनाशकों को बुलाए जाने के बाद एक शॉट में पूरे संगत हिस्से को मुक्त कर दिया है। (कार्यान्वयन के लिए कोई विकल्प नहीं होगा, जहां इसे हटाना [] ओवरराइड किया गया है)

+0

अनुवर्ती -अप सवाल http://stackoverflow.com/questions/32508952/does-delete-non-array-form-now-the-total-amount-of-memory-allocated-by-either पर ले जाया गया है – Rich

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