2010-03-11 15 views
21

मैं चाहता हूं कि मेरी कक्षा मेमोरी के गतिशील आवंटित क्षेत्र में स्थिर सूचक हो। मैं समझता हूं कि इसे कैसे प्रारंभ किया जाए - मेरे मामले में जब मैं पहली ऑब्जेक्ट की आवश्यकता होती हूं तो मैं इसे प्रारंभ कर दूंगा। हालांकि, मुझे नहीं पता कि कोड कब/कहाँ इसे मुक्त कर सकता है। कार्यक्रम समाप्त होने पर मैं इसे मुक्त करना चाहता हूं।सी ++ फ्रीिंग स्थिर चर

मैं अपने ऑब्जेक्ट्स के विनाशक में सूचक को मुक्त करने में सक्षम हो सकता हूं, लेकिन फिर मुझे ऑब्जेक्ट गिनती को बनाए रखना होगा ताकि यह देखने के लिए कि ऑब्जेक्ट उपयोग में आखिरी वस्तु है या नहीं।

क्या ऐसा करने के लिए एक और शानदार तरीका है?

कृपया मुझे बताएं।

धन्यवाद, jbu

+0

ध्वनि आप की तरह स्मार्ट संकेत बदलने की कोशिश कर रहे हैं? –

+0

यह समस्या उन मुद्दों में से एक है जो सिंगलेट्स को लागू करते समय होती हैं (http://en.wikipedia.org/wiki/Singleton_pattern)। @ Klaim का कोड नमूना नीचे एक उदाहरण है। वे एक अच्छी चीज या क्रच हो सकते हैं। उनका दुरुपयोग मत करो। :) – Void

उत्तर

18

आप यहाँ दो समाधान है:

  1. हटाना न हटाएँ यह (आप, सही सी में हैं ++, आप नए का उपयोग करें और उन्हें हटाना;?)) । लगभग सभी ओएस आज आवेदन समाप्त होने के बाद भी एप्लिकेशन द्वारा आवंटित स्मृति को "मुक्त" करेंगे। लेकिन यह एक अच्छा समाधान नहीं है, जो उदाहरण के लिए पहचानने के लिए मेमोरी लीक को कठिन बनाता है।
  2. अपने पॉइंटर को कक्षा (सदस्य के रूप में) में एकीकृत करें, फिर इस कक्षा का उपयोग अपनी स्थिरता के प्रकार के रूप में करें। इस तरह, आप जानते हैं कि कक्षा के विनाशक को आवेदन के अंत में बुलाया जाएगा। फिर आप विनाशक में अपना डेटा हटा दें और काम पूरा हो गया है और साफ है। वह आरएआईआई की शक्ति है।

मेरा सुझाव है कि आप 2 करते हैं, यह करने के लिए यह वास्तव में एक साफ तरीका है।


यहां एक साधारण उदाहरण है। इसके बजाय ऐसा करने से

static Thing* things = new Thing(); // or whatever way to initialize, here or in a specific function 

आप ऐसा करेंगे:

class ThingManager // or whatever name you like 
{ 
public: 
    ThingManager(Thing* thing) : m_thing(thing) { }//or create it here? whatever solution suits your way of creating the data 

    ~ThingManager() { delete m_thing; } // THAT's the important part! 

    Thing* instance() const { return m_thing; } // or whatever accessor you need, if you need one 

private: 
    Thing* m_thing; 
}; 

और फिर

static ManagedThing thing; // now i can access it via thing.instance() 

जब कार्यक्रम समाप्त होता है, स्थिर चर (कि अब और सूचक नहीं है) नष्ट कर दिया जाएगा और यह विनाशक ऐसा करने के लिए बुलाया जाएगा।

यह आपको यह बताने के लिए लिखा गया है कि आप यह कैसे कर सकते हैं।

+0

क्षमा करें, मैं सी ++ के लिए बहुत नया हूं। जब आप कहते हैं "कक्षा के विनाशक को आवेदन के अंत में बुलाया जाएगा" क्या आप कह रहे हैं कि एक वस्तु विनाशक और एक स्थिर वर्ग विनाशक है? इसके अलावा, आरएआईआई क्या है? – jbu

+0

आरए II: http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization आप सभी वर्गों के डिफ़ॉल्ट कार्यों के बारे में सीखना चाहिए। – Klaim

+4

आरएआईआई एक दुर्भाग्यपूर्ण शब्द है, क्योंकि यह बहुत वर्णनात्मक नहीं है; http://en.wikipedia.org/wiki/RAII –

2

आप एक स्थिर सूचक के रूप में स्थिर चर घोषित कर सकते हैं, फिर प्रोग्राम आवंटित सूचक को समाप्त कर दिया जाएगा।

0

मैं ट्रैक करने के लिए कक्षा में एक स्थिर काउंटर परिभाषित करेगा वस्तु उदाहरणों गिनती के रूप में नाशक यह काउंटर और अगर काउंटर == 0 मुक्त स्मृति भी .. बस आप के रूप में

6

ओएस से घटती निष्पादित मिल परिप्रेक्ष्य में, स्मृति को मुक्त करने में कोई वास्तविक बिंदु नहीं है क्योंकि आपका प्रोग्राम समाप्त हो जाता है, जो कुछ भी धीमा हो जाता है। आपके आवेदन की समाप्ति आपके पूरे पता स्थान को आँसू देती है, यह सब कुछ मुक्त कर देगा, आप एक ही समय में ढेर पर आवंटित करते हैं। स्पष्ट रूप से free को ऐप शट डाउन पर कॉल करने से ढेर में केवल पॉइंटर्स को घुमाया जा रहा है जो किसी भी तरह से फेंक दिया जाएगा।

मुख्य कारण है कि हम स्पष्ट रूप से सब कुछ को मुक्त करने के इतनी मेहनत की कोशिश करें कि हम स्मृति लीक नहीं कर रहे हैं और हमारी स्मृति पदचिह्न हमेशा के लिए नहीं उगता हो रहा है।

लेकिन यदि आप निश्चित हो सकते हैं कि यह स्थिर है, तो केवल एक ही होगा, और आप इसे सुरक्षित रूप से तब तक मुक्त नहीं कर सकते जब तक कि आपकी सभी अन्य वस्तुओं को मुक्त नहीं किया जाता है, यह एक ऐसा मामला है जहां यह बेहतर हो सकता है सिर्फ आवेदन समाप्ति को आपके लिए ख्याल रखना है।

+0

प्रतिक्रिया के लिए धन्यवाद। मैंने हमेशा सोचा था कि मेमोरी लीक ओएस को कार्यक्रम समाप्त होने के बाद भी आरक्षित/मुक्त स्मृति पर रखेगी। – jbu

+1

@jbu: अगर ऐसा हुआ तो यह एक बहुत अच्छा ओएस नहीं होगा। ;) –

+2

एल्थॉट जो कुछ मेमोरी-लीक डिटेक्शन टूल्स के साथ अन्य मेमोरी लीक मास्क करेगा, इसलिए इसे किसी भी तरह से अनुशंसित नहीं किया जाता है। – Klaim

14

एक स्मार्ट सूचक में फेंक। यह स्थिर जीवन होगा और main रिटर्न के बाद नष्ट कर दिया जाना:

// static 
void YourClass::freePointer(void) 
{ 
    delete getPointer(); 
} 

// static 
T* YourClass::getPointer(void) 
{ 
    if (!thePointer) 
    { 
     thePointer = new T; 
     atexit(freePointer); 
    } 

    return thePointer; 
} 

कौन सा वैसा ही प्रभाव पड़ेगा:

static std::auto_ptr<T> thePointer; 

एक अन्य विकल्प अपने स्वयं के atexit समारोह रजिस्टर करने के लिए है। एक और विकल्प जिसका आप पहले से उल्लेख करते हैं वह एक स्थिर काउंटर रखना है। ध्यान दें कि आप वास्तव में इसे बहुत प्रभावी ढंग से लपेट सकते हैं।

+1

अलेक्जेंड्रेस्कू अपने 'लोकी :: सिंगलटन' के कार्यान्वयन में 'एटएक्सिट 'का उपयोग करता है।इस तरह वह सुनिश्चित करता है कि पॉइंटर को मुक्त करने वाली विधियां भी अपने राज्य को '0' पर रीसेट कर देती हैं ताकि यदि आवश्यक हो तो इसे फिर से आवंटित किया जा सकता है ('फीनिक्स' जीवनकाल नीति का मामला)। व्यक्तिगत रूप से मुझे लगता है कि 'auto_ptr' या इससे भी बेहतर' unique_ptr' बहुत कम परेशानी है। –

+0

यह अच्छा नहीं है, केवल at_exit क्लीनअप फ़ंक्शन की एक छोटी सीमित संख्या है, कभी-कभी 32 के रूप में कम (मानक में परिभाषित न्यूनतम) – Lothar

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