कृपया ध्यान दें कि मैं अपने प्रश्न के साथ किसी भी समस्या का समाधान नहीं करना चाहते हैं - मैं बातें होती हैं करने के लिए की संभावनाओं के बारे में सोच रहा था और इस तरह कुछ के बारे में सोच रहा था:यदि आप कोई ऑब्जेक्ट हटाते हैं तो वास्तव में क्या होता है? (जीसीसी) (जब दुर्घटनाओं डबल हटाना चाहते हैं?)
यदि आप ऑब्जेक्ट पर हटाते हैं और जीसीसी को कंपाइलर के रूप में उपयोग करते हैं तो वास्तव में क्या होता है?
पिछले हफ्ते मैं एक दुर्घटना की जांच कर रहा था, जहां एक दौड़ की स्थिति किसी वस्तु के दोहरे डिलीट की ओर ले जाती है।
ऑब्जेक्ट के वर्चुअल विनाशक को कॉल करते समय क्रैश हुआ, क्योंकि वर्चुअल फ़ंक्शन तालिका के पॉइंटर को पहले ही ओवरराइट किया गया था।
क्या वर्चुअल फ़ंक्शन पॉइंटर पहले डिलीट द्वारा ओवरराइट किया गया है?
यदि नहीं, तो दूसरा हटाना सुरक्षित है, जब तक इस दौरान कोई नई स्मृति आवंटन नहीं किया जाता है?
मुझे आश्चर्य है कि मुझे पहले की समस्या क्यों पहचान नहीं मिली थी और केवल उन्मूलन यह है कि या तो वर्चुअल फ़ंक्शन तालिका को पहले डिलीट के दौरान तत्काल ओवरराइट किया जाता है या दूसरा डिलीट क्रैश नहीं होता है।
(पहला मतलब है कि "दौड़" होने पर दुर्घटना हमेशा एक ही स्थान पर होती है - दूसरा, आमतौर पर दौड़ होने पर कुछ भी नहीं होता है - और केवल तभी जब कोई तीसरा धागा डिलीट ऑब्जेक्ट को ओवरराइट करता है इस बीच समस्या तब होती है)
संपादित करें/अद्यतन:।
मैं एक परीक्षण, निम्नलिखित कोड एक segfault साथ दुर्घटनाओं था (जीसीसी 4.4, i686 और amd64):
012,351,class M
{
private:
int* ptr;
public:
M() {
ptr = new int[1];
}
virtual ~M() {delete ptr;}
};
int main(int argc, char** argv)
{
M* ptr = new M();
delete ptr;
delete ptr;
}
अगर मैं dtor से 'वर्चुअल' को हटा देता हूं, तो प्रोग्राम glibc द्वारा छोड़ा जाता है क्योंकि यह डबल-फ्री का पता लगाता है। 'वर्चुअल' के साथ क्रैश तब होता है जब अप्रत्यक्ष फ़ंक्शन को विनाशक को कॉल करते हैं, क्योंकि वर्चुअल फ़ंक्शन तालिका का सूचक अमान्य है।
दोनों amd64 और i686 पर पॉइंटर एक मान्य मेमोरी क्षेत्र (ढेर) को इंगित करता है, लेकिन मूल्य अमान्य है (काउंटर? यह बहुत कम है, उदाहरण के लिए 0x11, या 0x21) तो 'कॉल' (या 'jmp 'जब संकलक ने रिटर्न-ऑप्टिमाइज़ेशन किया था) एक अमान्य क्षेत्र में कूदता है।
कार्यक्रम संकेत SIGSEGV,
विभाजन गलती प्राप्त किया। 0x0000000000000021
में ??() (जीडीबी)
#
0x0000000000000021 में ??()
#
1 मुख्य() में 0x000000000040083e
तो ऊपर उल्लेख किया है शर्तों के साथ, आभासी समारोह मेज पर सूचक हमेशा द्वारा ओवरराइट है पहले, हटाने इसलिए अगले हटाने निर्वाण अगर पर चला जाएगा कक्षा में एक आभासी विनाशक है।
ध्वनि भी –
0A0D: यह मेरा prelimary समाधान (वैकल्पिक हल) है। असल में एक डिजाइन दोष था, क्योंकि यह निष्ठावान था कि वहां दो धागे हैं जो वस्तु को हटा सकते हैं। – IanH