2010-08-27 19 views
14

क्या इसमें कोई अंतर है:कौन सा ऑपरेटर हटाता है?

operator delete(some_pointer); 

और

delete some_pointer; 

और यदि ऐसा है तो अंतर क्या है और कहां से एक का उपयोग करना चाहिए और जहां इस ऑपरेटर का दूसरा संस्करण है? धन्यवाद।

+0

संभावित डुप्लिकेट [हटाएं बनाम \ [\] ऑपरेटरों को सी ++ में हटाएं] (http://stackoverflow.com/questions/2425728/delete-vs-delete-operators-in-c) –

+0

संबंधित http: // stackoverflow .com/प्रश्न/1 913343/कैसे-कर-जोड़-नई-साथ-हटा-संभवतः लीड-टू-मेमोरी-लीक-केवल –

+2

@ 0A0D: इस प्रश्न में सरणी हटाने के साथ कुछ भी नहीं है। – UncleBens

उत्तर

22

विडंबना यह है कि delete ऑपरेटर और operator delete() समान नहीं हैं।

delete some_pointer; ऑब्जेक्ट के विनाशक को some_pointer द्वारा इंगित करता है, और फिर स्मृति को मुक्त करने के लिए operator delete() पर कॉल करता है।

आप आम तौर पर operator delete() सीधे कॉल नहीं है, क्योंकि अगर आप ऐसा करेंगे, वस्तु नाशक नहीं कहा जा जाएगा, और आप मेमोरी लीक के साथ खत्म हो जाने की संभावना है।

केवल operator delete() पर ध्यान देने के लिए आपको केवल operator new() और operator delete() ओवरराइड करके अपना स्वयं का मेमोरी प्रबंधन करना है।

इसे ऊपर करने के लिए, आपको यह भी पता होना चाहिए कि delete और delete [] दो अलग-अलग चीजें हैं।

+2

वही है जो मैं ढूंढ रहा था। धन्यवाद। –

2

delete some_pointer; "सही" का उपयोग करने के एक है।

operator delete(some_Pointer); मुख्य रूप से आपके स्वयं के डिलीट ऑपरेटर को परिभाषित करने के लिए वाक्यविन्यास का एक आर्टिफैक्ट मौजूद है। ऐसा इसलिए है, क्योंकि आप प्लस ऑपरेटर को परिभाषित करते हैं;

myclass::operator+(myclass b) {....} 

तुम सच में लिख सकते हैं:

myclass c = a.operator+(b); 

लेकिन कोई भी कभी भी है कि नहीं करता है। वे का उपयोग करें:

myclass c = a + b; 

इसी तरह, आप operator delete(some_Pointer); लिख सकता है, लेकिन कोई भी कभी भी नहीं करता है।

+2

वे वास्तव में एक ही बात नहीं कर रहे हैं ... – Dima

+0

@Dima: मेरा उत्तर में किस बिंदु पर मैं कहा था कि वे एक ही बात कर रहे थे ?? मैंने अभी "कुछ_Pointer हटाएं" का उपयोग करने के लिए कहा है और आप कर सकते हैं, लेकिन कोई भी नहीं करता है, दूसरे फॉर्म का उपयोग करें। –

+3

आपका जवाब यह है कि के बारे में स्पष्ट नहीं है ... –

6

operator delete() बस स्मृति को मुक्त कर देते। delete some_pointersome_pointer के विनाशक को कॉल करता है, और फिर operator delete() पर कॉल करता है।

2

कम से कम मेरे अनुभव में, यह कोoperator new और operator delete से वास्तव में है (यानी, कॉल) उन्हें इस्तेमाल करने को लागू, कम से कम सीधे और अधिक आम है।

आमतौर पर, आप operator new और operator delete परोक्ष रूप से उपयोग करें - आप एक new expression लिखते हैं, A *a = new A; की तरह। इसे लागू करने के, संकलक उत्पन्न कोड है कि operator new invokes कच्चे स्मृति को आबंटित करने, तो एक A::A invokes एक A वस्तु में कि कच्चे स्मृति कन्वर्ट करने के लिए, जैसा कि अगर आप लिखा था:

void *temp = operator new(sizeof A); // allocate raw memory with operator new 
A *a = new(temp) A;     // convert raw memory to object with placement new 

जब आप पूरा कर ऑब्जेक्ट के साथ, आप delete A; का उपयोग करते हैं।कि लागू करने के लिए, संकलक वस्तु के लिए dtor invokes, और फिर स्मृति को मुक्त कर देते, मोटे तौर पर की तरह आप कर चाहते हैं:

a->~A(); 
operator delete(a); 

वहाँ भी operator [] new और operator [] delete कर रहे हैं, जो जब/अगर आप आवंटित/हटाने उपयोग किया जाता है सरणी - लेकिन सामान्य संस्करण और सरणी संस्करण के बीच कोई वास्तविक अंतर नहीं है - वे दोनों केवल निर्दिष्ट मात्रा में कच्ची मेमोरी आवंटित करते हैं (हालांकि आप अनुमान लगा सकते हैं कि सरणी संस्करण अपेक्षाकृत बड़ी मात्रा में स्मृति आवंटित करेंगे , और उस आधार पर कुछ अनुकूलन करें)।

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

एक दिलचस्प छोटे से tidbit: operator new, operator [] new, operator delete और ऑपरेटर [] उनकी घोषणा/परिभाषा are always स्थिर class members, even if you don't explicitly include static` को हटा दें।

भी सभी चार (::operator new, ::operator [] new, ::operator delete और ::operator [] delete) के वैश्विक संस्करण हैं। ये "आंतरिक" सी ++ मेमोरी प्रबंधन, और बाहरी दुनिया के बीच "सीमा" को चिह्नित करते हैं। आम तौर पर वे ऑपरेटिंग सिस्टम से स्मृति के अपेक्षाकृत बड़े हिस्से आवंटित करते हैं, और फिर अनुरोध पर शेष कार्यक्रमों में छोटे टुकड़े लौटाते हैं। यदि आप अपने पूरे कार्यक्रम के लिए मेमोरी प्रबंधन को अनुकूलित करना चाहते हैं (तो कोशिश करें), तो आप आमतौर पर इनलोडिंग (या, वास्तव में, प्रतिस्थापित) करके इसे करते हैं। फिर, सामान्य कारण यह होगा कि यदि आप बहुत सी छोटी वस्तुओं को आवंटित करने की उम्मीद करते हैं (लेकिन केवल कुछ कक्षाओं में नहीं)। इसका एक उदाहरण Boost Pool लाइब्रेरी है।

उपरोक्त में से किसी का सीधा उपयोग आम तौर पर स्थितियों में, जहां आप कच्चे स्मृति का एक ब्लॉक की जरूरत है, नहीं वस्तुओं तक ही सीमित है। एक उदाहरण आपके स्वयं के कंटेनर कक्षाओं को लागू करेगा। उदाहरण के लिए, std::vector आमतौर पर वस्तुओं को संग्रहीत करने के लिए मेमोरी आवंटित करने के लिए ::operator new (ऑलोकेटर ऑब्जेक्ट के माध्यम से) का उपयोग करता है। चूंकि इसे स्टोरेज आवंटित करने में सक्षम होना आवश्यक है, लेकिन बाद में (या शायद कभी नहीं) उस भंडारण में ऑब्जेक्ट्स बनाते हैं, यह केवल data = new T[size]; जैसे कुछ का उपयोग नहीं कर सकता - इसे कच्ची मेमोरी आवंटित करनी है, फिर वस्तुओं को बनाने के लिए प्लेसमेंट नया उपयोग करें स्मृति के रूप में आप उन्हें संग्रह में जोड़ते हैं (उदाहरण के लिए, जब आप push_back कोई ऑब्जेक्ट)। std::deque के साथ भी यही सच है। यदि आप भंडारण के लिए vector जैसे कुछ का उपयोग करने के बजाय सीधे सभी मेमोरी प्रबंधन को संभालने के लिए "ग्राउंड अप से" अपने परिपत्र बफर को लागू करने के लिए (उदाहरण के लिए) चाहते थे, तो आपको शायद इसकी आवश्यकता होगी/चाहें।

+0

बहुत अच्छा जवाब धन्यवाद –

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