2010-08-07 2 views
6

में फ़ंक्शन हटाएं मैंने फ़ंक्शन का उपयोग करने का एक उदाहरण देखा: सीपीपी में हटाएं और मैंने इसे पूरी तरह से समझ नहीं लिया। कोड है:सी ++

class Name { 
    const char* s; 
    //... 
}; 

class Table { 
     Name* p; 
     size_t sz; 
public: 
     Table(size_t s = 15){p = new Name[sz = s]; } 
     ~Table { delete[] p; } 
}; 

आदेश का सही कार्रवाई क्या है: delete[] p;?

मुझे लगता है कि उद्देश्य कंटेनर तालिका में सभी पॉइंटर्स को हटाना था।

delete[] में ब्रैकेट मुझे एक सुराग देते हैं कि यह नाम पर पॉइंटर्स की एक सरणी हटा देता है लेकिन सरणी का आकार निर्दिष्ट नहीं है, तो विनाशक कैसे जानता है कि कितने पॉइंटर्स को हटाना है?

+0

संभावित डुप्लिकेट [हटाएं बनाम \ [\] ऑपरेटरों को सी ++ में हटाएं] (http://stackoverflow.com/questions/2425728/delete-vs-delete-operators-in-c) और [इसमें कैसे हटाया जाता है सी ++ जानते हैं कि कितने मेमोरी स्थानों को हटाना है] (http://stackoverflow.com/questions/2327848/how-does-the-delete-in-c-now-how-many-memory-locations-to-delete) –

+1

" सभी पॉइंटर्स "- ध्यान दें कि 'तालिका' में केवल एक पॉइंटर होता है। यह 'नाम' की गतिशील रूप से आवंटित सरणी के लिए एक सूचक है, लेकिन केवल एक गतिशील रूप से बनाई गई वस्तु (सरणी) है जिसे हटाया जाना आवश्यक है। –

उत्तर

13

delete कोई फ़ंक्शन नहीं है, यह एक ऑपरेटर है।

[] का उपयोग करके अभिव्यक्ति new ... [] के साथ बनाई गई वस्तुओं को नष्ट कर देती है और संबंधित स्मृति को रिलीज़ करती है। delete[]new ... [] द्वारा लौटाए गए पॉइंटर्स के लिए उपयोग किया जाना चाहिए; गैर-सरणी delete केवल गैर-सरणी new द्वारा लौटाए गए पॉइंटर्स पर। गैर-मिलान delete फ़ॉर्म का उपयोग करना हमेशा गलत होता है।

~Table() में delete अभिव्यक्ति (अपने कोड में () लापता) यह सुनिश्चित करना कि Name नाशक सरणी के प्रत्येक सदस्य के लिए कहा जाता है Name वस्तुओं की डायनामिक रूप से तैयार सरणी नष्ट कर देगा।

यह new ... [] के साथ आवंटित सरणी में तत्वों की संख्या रिकॉर्ड करने के कुछ तंत्र को कार्यान्वित करने के कार्यान्वयन पर लागू है, प्रोग्रामर को इसके बारे में चिंता करने की आवश्यकता नहीं है।

कई कार्यान्वयन में, जहां सरणी तत्वों में गैर-तुच्छ विनाशक होते हैं, new[] अभिव्यक्ति सभी सरणी सदस्यों के लिए स्थान से पहले तत्व गणना को रिकॉर्ड करने के लिए अतिरिक्त स्थान आवंटित करेगी। यह छिपी गिनती तब देखी जाती है जब delete[] का उपयोग यह सुनिश्चित करने के लिए किया जाता है कि विनाशकों की सही संख्या कहा जाता है। यह सिर्फ एक कार्यान्वयन विस्तार है, हालांकि, अन्य कार्यान्वयन संभव है।

+0

1) कोड में कई वस्तुओं को नए के साथ शुरू किया जा सकता है ... [] उनमें से कौन सा हटाकर नष्ट हो गया है? 2) उदाहरण कोड() में भी गायब थे। –

+2

@ डेय_Dreamer: इसके बारे में सोचने का एक और तरीका कई वस्तुओं की एक सरणी के रूप में है। 'नया नाम [sz]' एक सरणी (कई ऑब्जेक्ट्स) आवंटित करता है 'हटाएं []' एक सरणी (कई ऑब्जेक्ट्स) को हटा देता है। सरणी नष्ट होने पर सरणी के प्रत्येक सदस्य को नष्ट कर दिया जाता है। –

1

संक्षेप में, delete[] उस सरणी के आकार को जानता है जो इसे हटा रहा है क्योंकि इसकी आवश्यकता है।

क्योंकि सी ++ भाषा मानक बताता है कि उसे पता होना चाहिए। तो जब आप एक सरणी आवंटित करते हैं, तो यह कहीं भी आकार को स्टोर करने के लिए सिस्टम पर निर्भर करता है जहां delete[] इसे ढूंढ सकता है।

एक विकल्प आवश्यक से कुछ बाइट आवंटित करना है। आकार निर्दिष्ट करने के लिए पहले बाइट्स का उपयोग करें, और उसके बाद पहले आवंटित बाइट में पॉइंटर लौटने की बजाय, आकार फ़ील्ड के पहले बाइट में एक पॉइंटर लौटाएं।

फिर delete[] आकार को खोजने के लिए केवल पॉइंटर से कुछ बाइट घटाएं।

एक और विकल्प वैश्विक map<void*, int> होना चाहिए, जहां कुंजी स्मृति आवंटन के लिए सूचक है, और मान उस आवंटन का आकार है। ऐसे कई अन्य तरीके हैं जिनमें delete[] आकार का पता लगा सकते हैं। सी ++ मानक निर्दिष्ट नहीं करता कि किस का उपयोग करना है। यह सिर्फ इतना कहता है कि delete[] आकार को जानना चाहिए, और को को खींचने के लिए इसे लागू करने के लिए कार्यान्वयनकर्ताओं को छोड़ देना चाहिए।

+0

जोड़ी के तंत्र का कार्यान्वयन कहां है: हटाएं और नया? रनटाइम लाइब्रेरी में –

+0

, जो आमतौर पर संकलक के साथ प्रदान किया जाता है। – jalf