का उपयोग करते समय अजीब डबल विनाशक कॉल अंत में मैंने बहुत अजीब बग को ट्रैक किया, जो डबल कॉलिंग विनाशक के कारण होता है।share_ptr
#include <iostream>
#include <memory>
#include <set>
class cEventSystem {
public:
cEventSystem() {
std::cout << "constructor: " << this << std::endl;
}
~cEventSystem() {
std::cout << "destructor: " << this << std::endl;
}
};
class cSubscriber {
public:
cSubscriber(cEventSystem& eventSystem) : eventSystem(eventSystem) {}
virtual ~cSubscriber() {}
virtual void onEvent() = 0;
protected:
cEventSystem& eventSystem;
};
class cTileBrowser: public cSubscriber {
public:
cTileBrowser(cEventSystem eventSystem) : cSubscriber(eventSystem) {}
void onEvent() {}
};
class cGui: public cSubscriber {
public:
cGui(cEventSystem& eventSystem) : cSubscriber(eventSystem) {
tileBrowser = std::make_shared<cTileBrowser>(eventSystem);
}
void onEvent() {}
std::shared_ptr<cTileBrowser> tileBrowser;
};
int main() {
cEventSystem eventSystem;
cGui gui(eventSystem);
}
उत्पादन होता है:: यहाँ कम से कम कोड है कि बग को पुनरुत्पादित करता है
constructor: 0x7fffffffe67f
destructor: 0x7fffffffe2df
destructor: 0x7fffffffe67f
आप देख सकते हैं पहले नाशक अवांछित है और यह विभिन्न वस्तु, जिस पर निर्माण नहीं किया गया था पर कहा जाता है सब (एड्रेस अलग है), लेकिन मेरे असली कोड में एड्रेस काफी करीब है और यह घटना प्रणाली में मौजूद कंटेनर को दूषित करता है।
डीबगिंग से पता चलता है कि यह make_shared है जो विनाशक कॉल का कारण बनता है।
क्या अवांछित विनाशक कॉल का कारण बनता है और मैं इससे कैसे छुटकारा पा सकता हूं? मैं सी ++ 11 ध्वज के साथ जी ++ 4.7 का उपयोग करता हूं।
समस्या यह है कि अवांछित नाशक कॉल आमतौर पर (90 बार का%) मेरा असली कोड जो segfaults का कारण बनता है में अपने घटना प्रणाली कंटेनरों को बिगाड़ देती है, लेकिन शायद ही कभी यह यह भ्रष्ट नहीं है और सब कुछ काम करता है।
आदमी, आप नायक हैं, यह अब मेरे असली कोड में काम करता है! लेकिन अस्थायी प्रति इतनी असुरक्षित क्यों है कि यह मेरे डेटा को स्मृति में दूषित कर सकती है? मैं लगभग हमेशा संदर्भ से गुजरता हूं (यह एक गलती थी), लेकिन यह मेरे लिए कम से कम अजीब लगता है। – user1873947
@ user1873947, चूंकि कॉपी कन्स्ट्रक्टर संकलक उत्पन्न होता है, यह शायद गलत चीज कर रहा है। यदि यह उदाहरण के लिए पॉइंटर की एक प्रति बनाता है और विनाशक इसे हटा देता है, तो आपको मूल ऑब्जेक्ट में एक खतरनाक पॉइंटर के साथ छोड़ दिया जाता है। –
@ मार्क रान्ससम यह है। मेरे असली कोड में मेरे पास पॉइंटर्स का एक सेट है। – user1873947