2010-11-24 15 views
9

निम्नलिखित कोड झूलने संदर्भ का उत्पादन:उलझन संदर्भ। पॉइंटर्स और संदर्भों को लटकाने के विकल्प?

int main() 
{ 
    int *myArray = new int[2]{ 100, 200 }; 
    int &ref = myArray[0]; 
    delete[] myArray; 
    cout << ref; // Use of dangling reference. 
} 

मैं जानता हूँ कि मैं सरणी को नष्ट नहीं करना चाहिए, लेकिन एक बड़े कार्यक्रम क्या हुआ अगर किसी को स्मृति हटाता में करने के लिए जो मैं एक संदर्भ है? क्या किसी भी तरह से आश्वासन दिया जा सकता है कि कोई भी सरणी को हटा देता है?

संदर्भों को लटकाने और लटकने वाले पॉइंटर्स के खिलाफ सबसे अच्छी रणनीति क्या है?

+0

शायद 'boost :: shared_ptr'। –

+1

http://stackoverflow.com/questions/395123/raii-and-smart-pointers-in-c। या इस उदाहरण में, सबसे अच्छा विकल्प यह नहीं करना है। –

+1

एक गतिशील आवंटित सरणी का सबसे अच्छा विकल्प 'std :: vector' है। 'नया []' और 'हटाएं [] 'का उपयोग करने के लिए सी ++ में व्यावहारिक रूप से बहुत कम आवश्यकता है। - लेकिन फिर भी, इटेटर और संदर्भ आसानी से अवैध हो जाते हैं। आम तौर पर आपको उन चीजों के लिए दीर्घकालिक संदर्भ नहीं होना चाहिए जिनके पास लंबे जीवनकाल नहीं हो सकते हैं। – UncleBens

उत्तर

12

इससे पहले कि आप इसे समाप्त कर लें, स्मृति को हटाएं।

बेवकूफ लगता है, लेकिन यह आपकी एकमात्र सुरक्षा है - ठीक से समझें कि प्रत्येक चर के पीछे स्मृति का मालिक कौन है, और जब इसे सुरक्षित रूप से मुक्त किया जा सकता है।

स्मार्ट पॉइंटर्स मदद कर सकते हैं, लेकिन उपरोक्त अभी भी लागू होता है।

यह संभव है कि कुछ स्थिर विश्लेषण उपकरण आपके यहां मौजूद मामूली मामले की पहचान कर सकें, लेकिन फिर भी यह स्मृति प्रबंधन में आपके पहले अनुशासन के साथ रक्षा की दूसरी पंक्ति होनी चाहिए।

+0

+1, बहुत कुछ :) –

+1

मुझे पता है कि मुझे स्मृति को हटाना नहीं चाहिए, लेकिन इसे बड़े कार्यक्रम में नियंत्रित नहीं किया जा सकता है। मैं सभी डेवलपर्स से arrayXYZ को हटाने के लिए नहीं कह सकता हूं। लेकिन मुझे लगता है कि स्मार्टपॉइंटर्स जो मैं ढूंढ रहा था। धन्यवाद स्टीव – blueskin

+0

लेकिन फिर समस्या यह है कि मेरे पास स्मार्ट पॉइंटर्स का संग्रह या सरणी नहीं हो सकती है, क्या मैं कर सकता हूं? – blueskin

7

रखें उन्हें ठीक से scoped:

int main(){ 
    int *myArray; 
    myArray = new int[2]{ 100, 200 }; 
    { 
    int& ref = myArray[0]; 
    // use the ref here 
    cout<<ref; \\no longer a dangling reference 
    } // ref falls out of scope here 
    delete[] myArray; 
} 
+0

अच्छा बिंदु - जब भी संभव हो RAII और स्कोपिंग का उपयोग करें। –

3

अच्छा प्रोग्रामिंग प्रथाओं। कंपाइलर आपको अपने आप को लटकने के लिए पर्याप्त रस्सी से अधिक देता है; यह सुनिश्चित करना आपकी ज़िम्मेदारी है कि आप नहीं करते हैं।

दूसरे शब्दों में, यदि आप किसी सरणी के संदर्भ नहीं लेते हैं, और फिर इसे हटा दें, तो आपको कोई समस्या नहीं होगी।

"लेकिन, अगर ऐसा होता है तो क्या होगा?"

वास्तव में कोई आसान जवाब नहीं है। यह प्रशिक्षण के बारे में है, और यह जानने के लिए कि आप जिस उपकरण का उपयोग करने का प्रयास कर रहे हैं उसका उपयोग कैसे करें।

+1

"अपने आप को लटका देने के लिए पर्याप्त रस्सी" .. एलओएल .. यह सच है – blueskin

3

रोगी: डॉक्टर, यह दर्द होता है जब मैं इस ...

डॉक्टर करते हैं: तो फिर इसे बंद ...

जबकि यह के लिए एक संदर्भ होने स्मृति जारी न करें।


संपादित

को पकड़ने के लिए है कि डिबग करने के लिए है एक ही तरीका है, अच्छा इकाई परीक्षण किया है और valgrind के तहत चलाने के लिए, या valgrind के तहत अपने कार्यक्रम चलाते हैं।

+0

मैंने प्रश्न में और भी जोड़ा। मेरा सवाल पूरी तरह से प्रतिनिधित्व नहीं कर रहा था जो मैं पूछने की कोशिश कर रहा था। धन्यवाद – blueskin

+1

@blueskin उत्तर (और अन्य सभी) अभी भी मान्य हैं। "ऐसा मत करें", और यह जांचने के कोई तरीके नहीं हैं कि आपका संदर्भ अमान्य है (या अमान्य स्मृति स्थान पर सूचक बिंदु) –

+1

या .. मैं समझता हूं। दुख की बात यह सच है .. अगर मुझे अपने साक्षात्कार में यह पूछा जाए और समाधान के लिए कहा जाए तो क्या होगा। मैं नहीं कह सकता "ऐसा मत करो": डी .. – blueskin

3

यहां सभी उत्तरों "सावधान रहें!" और "अच्छे प्रोग्रामिंग प्रथाओं का उपयोग करें!"।
यह एक बहुत ही संतोषजनक उत्तर नहीं है। ये समस्याएं 40+ वर्षों से सी में मौजूद हैं, और वे अभी भी महत्वपूर्ण आकार के किसी भी सी ++ प्रोजेक्ट में आम हैं।

सबसे बड़ी दिशानिर्देश आपको सुनेंगे लोगों की सिफारिश कर रहे हैं:

  • उपयोग स्मार्ट संकेत
  • उपयोग आरए II

दोनों सत्य हैं, लेकिन वहाँ है और अधिक आप कर सकते हैं।

2015 में, मानक सी ++ फाउंडेशन ने Guidelines Support Library जारी किया।

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

मैं तुम्हें एक स्थिर विश्लेषण उपकरण के साथ GSL के Owner<> का उपयोग करें।
यह सुरक्षित व्यवहार की गारंटी देगा।

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