2010-12-04 8 views
10

मैं इसे में अन्य वस्तुओं की ओर इशारा का एक वेक्टर के साथ एक वस्तु, कुछ इस तरह है:क्या एक गैर-नई वस्तु को हटाना संभव है?

Object obj; 
obj.objlist.push_back(new Object); 

और:

class Object { 
    ... 
    vector<Object*> objlist; 
    ... 
}; 

अब, वस्तुओं को इनमें से दोनों में सूचीबद्ध करने के लिए जोड़ दिया जाएगा

Object name; 
Object* anon = &name; 
obj.objlist.push_back(anon); 

तो एक एक नाशक बस

है कि बनाने के

क्या कोई ऑब्जेक्ट हटाने की कोशिश करता है जब यह किसी ऑब्जेक्ट को हटाने की कोशिश करता है जो नए के साथ नहीं बनाया गया था?

+0

मुझे पता है कि यह एक पुनरावर्तक के साथ बेहतर हो सकता है, लेकिन 'objlist' मूल रूप से और सरणी थी और मुझे लूप बदलने के लिए चारों ओर नहीं मिला है। –

उत्तर

28

हां, प्रतिकूल प्रभाव होंगे।

आपको delete एक ऑब्जेक्ट नहीं होना चाहिए जो new के साथ आवंटित नहीं किया गया था। यदि वस्तु को ढेर पर आवंटित किया गया था, तो आपके कंपाइलर ने अपने दायरे के अंत में अपने विनाशक को पहले ही कॉल कर दिया है। इसका मतलब है कि संभावित रूप से बहुत बुरे प्रभावों के साथ आप विनाशक को दो बार बुलाएंगे।

विनाशक को दो बार कॉल करने के अलावा, आप कभी भी आवंटित मेमोरी ब्लॉक को रद्द करने का प्रयास करेंगे। new ऑपरेटर संभावित रूप से ढेर पर वस्तुओं को रखता है; delete उसी क्षेत्र में ऑब्जेक्ट को खोजने की अपेक्षा करता है new ऑपरेटर उन्हें रखता है। हालांकि, आपकी ऑब्जेक्ट जिसे new के साथ आवंटित नहीं किया गया था, स्टैक पर रहता है। यह शायद आपके प्रोग्राम को क्रैश करेगा (यदि यह दूसरी बार विनाशक को कॉल करने के बाद पहले से ही क्रैश नहीं होता है)।

यदि आपके Object ढेर पर Object ढेर पर आपके Object से अधिक समय तक रहता है तो आपको गहरी परेशानी होगी: आपको स्टैक पर कहीं भी एक खतरनाक संदर्भ मिलेगा, और आपको गलत परिणाम/क्रैश मिलेगा अगली बार जब आप इसे एक्सेस करेंगे।

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

+0

मैं देखता हूं। यह सुनिश्चित करने के लिए कोई तरीका है कि ऑब्जेक्ट नष्ट हो जाने पर, ओबजलिस्ट में जो कुछ भी नया था, उसे हटा दिया गया है, और कुछ भी नहीं? –

+1

@ Keand64 वहां आपकी मदद करने के लिए कोई भाषा सुविधा नहीं है। एक बार आपके पास पॉइंटर हो जाने के बाद, आप (प्लेटफार्म-निर्भर अंधेरे जादू/असुरक्षित संचालन के बिना) नहीं जानते हैं कि यह स्टैक या ढेर पर कहीं कहीं इंगित करता है। ढेर पर रहने वाले ढेर और वस्तुओं पर रहने वाली वस्तुओं को मिश्रण करना आम तौर पर बुरा विचार है। आपकी सबसे अच्छी शर्त उन सभी के लिए 'new' का उपयोग करना होगा। – zneak

+0

@ केंड 64: आपको जो करना है, वह 'कोड' के लिए 'new' ing के लिए जिम्मेदार कोड बना रहा है। कंटेनरों के लिए, आप कंटेनर को रखे गए सबकुछ को स्पष्ट रूप से कॉपी करके, कंटेनर दोनों को करते हैं। (यह आपको कॉलिंग कोड के खिलाफ भी सुरक्षा देता है जो बिंदु-बिंदु पर दायरे से बाहर निकलता है।) लेकिन ** अपने स्वयं के कंटेनर को वैसे भी नहीं लिखें **; मानक पुस्तकालय आपको जो चाहिए वह प्रदान करता है। –

1

यह काम नहीं करेगा - यदि आप delete एक ऑब्जेक्ट जो new द्वारा आवंटित नहीं किया गया था, तो आपने नियमों का उल्लंघन किया है या delete ऑपरेटर।

यदि आपको अपने वेक्टर स्टोर ऑब्जेक्ट्स को हटाने की आवश्यकता हो सकती है जिन्हें हटाया जा सकता है या नहीं, तो आपको किसी भी तरह का ट्रैक रखने की आवश्यकता होगी। एक विकल्प एक स्मार्ट पॉइंटर का उपयोग करना है जो ट्रैक करता है कि ऑब्जेक्ट की ओर इशारा किया गया है या नहीं। उदाहरण के लिए, shared_ptr<> जब shard_ptr<> निर्माण आप एक deallocator वस्तु निर्दिष्ट करने के लिए और के रूप में किए गए दस्तावेज़ों का उल्लेख अनुमति देता है:

उदाहरण के लिए, एक "नहीं-op" deallocator उपयोगी होता है जब एक स्थिर आवंटित ऑब्जेक्ट में एक shared_ptr लौटने

हालांकि, आपको स्थिर चर के लिए पॉइंटर्स पास करते समय भी सावधान रहना चाहिए - यदि वेक्टर का जीवनकाल चर के जीवनकाल से अधिक लंबा है तो यह किसी बिंदु पर कचरा करने के लिए प्रतिक्रिया देगा।

3

नहीं, आप केवल delete क्या आप new एड कर सकते हैं

Object* anon = &name; 

नाम दायरे से बाहर चला जाता है, तो आप अपने वेक्टर में कोई अमान्य सूचक होगा।

1

आप वास्तव में क्या पूछ रहे हैं कि ऑपरेटर के माध्यम से ऑपरेटर के माध्यम से आवंटित ऑब्जेक्ट को हटाना सुरक्षित है, और यदि ऐसा है, तो क्यों?

दुर्भाग्यवश, यह आपके कोड में कुछ अन्य समस्याओं से गुमराह है। जैसा कि बताया गया है, जब नाम गुंजाइश से बाहर हो जाता है, तो आप एक अवैध सूचक के साथ समाप्त होने जा रहे हैं।

zneak's answer देखें कि क्यों आपका मूल प्रश्न सुरक्षित संचालन नहीं करता है, और नाम का दायरा वास्तव में क्यों मायने रखता है।