यदि मैं किसी ऑब्जेक्ट को हटा देता हूं जो इसके विनाशक को बुलाता है, तो क्या कार्यकर्ता पहले से या बाद में नष्ट हो गया है, जो कि कार्यकर्ता में जो भी हो रहा है?सी ++ विनाशक: जब स्मृति मुक्त हो जाती है?
उत्तर
मेमोरी केवल कम से कम व्युत्पन्न वर्ग सबोबजेक्ट नष्ट हो जाने के बाद ही मुक्त हो जाती है। तो अगर आप हैं:
class Base {
};
class Derived : public Base {
public:
~Derived();
};
तो पहले Derived
नष्ट हो जाता है, तो Base
नष्ट हो जाता है और उसके बाद ही स्मृति पुनः आवंटित की जाती है।
विनाशक समाप्त होने के बाद स्मृति मुक्त हो जाती है। अन्यथा, विनाशक के अंदर सदस्य चर का उपयोग सेगफाल्ट का कारण बन जाएगा।
ऑपरेटर को हटाने के नाशक के बाद कहा जाता है, लेकिन जब स्मृति मुक्त हो जाता है इस्तेमाल किया संभाजक
पर निर्भर है मुझे लगता है कि स्मृति नाशक समारोह में ही निष्पादन पूरा होने के बाद मुक्त हो जाता है लगता होगा। मुझे पता है कि जब एक अपवाद पकड़ा जाता है, तब वस्तु के विनाशक को तब तक नहीं बुलाया जाता है जब तक ऑब्जेक्ट स्वयं दायरे से बाहर न हो जाए।
delete
को वास्तव में क्या कर रहा है में विघटित करें और यह देखने के लिए अपेक्षाकृत स्पष्ट है कि स्मृति कब हटा दी जाती है। तो इस तरह एक बयान:
delete some_ptr;
मोटे तौर पर इस छद्म कोड के बराबर है:
some_ptr->~some_ptr();
free(some_ptr);
तो स्मृति नाशक करने के लिए कॉल के बाद मुक्त किया गया है। वास्तव में विनाशक delete
ऑपरेटर द्वारा निर्धारित नहीं है, बल्कि कक्षा की परिभाषा निर्धारित करता है। आमतौर पर यह स्थानीय सफाई करता है और यह सुनिश्चित करता है कि इसके बेस क्लास विनाशकों को भी बुलाया जाता है।
यह जानना महत्वपूर्ण है कि स्मृति को मुक्त करना वास्तव में विनाशक का हिस्सा नहीं है। यह delete
ऑपरेटर है जो स्मृति को मुक्त करता है।
नोट छद्म कोड में free
समारोह वास्तव में operator delete()
कार्यों में से एक यह है कि, या तो नष्ट कर दिया वर्ग, या वैश्विक लिए। वह वास्तव में स्मृति को मुक्त करता है।
यह 'मुक्त() 'नहीं है, यह' ऑपरेटर हटाएं()' है। – sharptooth
@ शार्पतोथ, क्या आप स्पष्टीकरण दे सकते हैं? मैंने उल्लेख किया कि 'छद्म कोड' था। –
भले ही यह छद्म कोड सी ++ 'हटाएं' कथन पर स्मृति को हटाने के लिए 'ऑपरेटर डिलीट() '- या तो वैश्विक या क्लास-विशिष्ट का उपयोग करता है। – sharptooth
सी ++ में, विनाश वस्तु में उपलब्ध डेटा का उपयोग करके कुछ कोड निष्पादित करने के बारे में है। यह कोड मनमाने ढंग से है।
स्मृति को मुक्त करना एक निम्न स्तर का हैंडलिंग है, जो delete
ऑपरेटर द्वारा सामान्य रूप से छिपा हुआ है, जिसे विनाशक को कॉल से पहले कभी नहीं कहा जाना चाहिए।
यह सबसे अच्छा Allocator इंटरफ़ेस द्वारा संक्षेप है:
allocate
औरdeallocate
कच्चे स्मृति में हेरफेर करने केconstruct
औरdestroy
उपयोग किया जाता है कंस्ट्रक्टर्स और वस्तुओं की विनाशकर्ता कॉल करने के लिए उपयोग किया जाता है
यह सटीक है कि construct
, destroy
और deallocate
केवल निष्पादित किया जाना चाहिए पहले आवंटित द्वारा आवंटित एन स्मृति। यह भी सटीक है कि destroy
स्मृति को अस्वीकार नहीं करता है, और बाद में deallocate
पर कॉल आवश्यक होगा।
ध्यान दें कि यह एक निम्न-स्तरीय इंटरफ़ेस है, जो किसी ऑब्जेक्ट को नष्ट करने और स्थानांतरित करने के लिए मुक्त स्थान का उपयोग करने की अनुमति देता है।
क्या वास्तव में ऐसी कोई चीज है? एक विशेष विनाशक कहा जाता है, जो वर्ग को वर्चुअल हो सकता है यदि कक्षा ने इसे घोषित किया हो। वह विनाशक सभी सबोबजेक्ट को नष्ट करने के लिए ज़िम्मेदार है, और फिर स्मृति मुक्त हो जाती है। आधार वर्गों के बिना सभी सबोबजेक्ट समान रूप से कम से कम व्युत्पन्न होते हैं, और किसी के पास विशेष जिम्मेदारी या महत्व नहीं होता है। – Potatoswatter
@Potatoswatter: नोट मैंने निर्दिष्ट नहीं किया है कि डेलोकेशन फ़ंक्शन को कॉल करने के लिए वास्तव में कौन जिम्मेदार है - ठीक है क्योंकि सभी विवरणों में ऐसा करने के लिए दो-पेज के उत्तर की आवश्यकता होगी। – sharptooth
@Potatoswatter: मुझे यकीन नहीं है कि मैं अनुसरण करता हूं। Subobjects को नष्ट करने के लिए कोई विनाशक जिम्मेदार नहीं है। विनाशक उस वस्तु में आयोजित संसाधनों को मुक्त करने के लिए ज़िम्मेदार है, लेकिन उसे अन्य वस्तुओं के विनाशक को कॉल करने की आवश्यकता नहीं है: 'कक्षा परीक्षण {स्ट्रिंग ए; ~ परीक्षण() {}}; '' test' destructor इस उदाहरण में पूरी तरह से परिभाषित किया गया है, कक्षा द्वारा सीधे प्रबंधित कोई संसाधन नहीं है और कुछ भी नहीं करता है। '~ Test' निष्पादन पूरा करने के बाद '' test'' के बाद '''' subobject पर सिस्टम' ~ स्ट्रिंग 'को कॉल करेगा। वही विरासत के साथ जाता है, आधार के विनाशक को स्वचालित रूप से बुलाया जाएगा। –