2010-11-03 16 views
8

मैं अपने आवेदन के भीतर एसटीएल string का उपयोग कर रहा हूं, और मैं हाल ही में मेमोरी लीक के लिए इसका परीक्षण कर रहा था, और मैंने देखा कि कार्यक्रम के अंत तक मेरे कई तारों को ठीक तरह से हटाया नहीं जा रहा था।सी/सी ++ स्ट्रिंग मेमोरी लीक?

मैं तार से एक के साथ निम्नलिखित कोड (शब्दशः नहीं) का परीक्षण किया:

const string* cppString = &obj->objString; 
const char* cString = cppString->c_str(); 
delete obj; 

उसके बाद, मैं एक ब्रेक सूत्री रख दिया और देखा, कि जब तक string कि cppString नहीं रह गया है अस्तित्व में की ओर इशारा किया, cString अभी भी एक सी-स्टाइल स्ट्रिंग को इंगित कर रहा था, जो निश्चित रूप से पर्याप्त था, वह अंत में समाप्त होने में असफल रहा था।

क्या मुझे सी/सी ++ तारों के काम के मामले में कुछ याद आ रही है? मैं स्ट्रिंग के सी प्रतिनिधित्व को भी हटाया जा सकता हूं?

संपादित करें: कुछ और जानकारी। मेरा obj वर्ग Dialog का प्रकार है, जो Popup विरासत में मिलता है। मैंने सोचा कि शायद यह हो सकता है, क्योंकि जब मैं obj हटाता हूं, तो मैं इसे Popup* के रूप में देख रहा हूं, लेकिन मैंने इसे एक छोटे से अलग कार्यक्रम में करने की कोशिश की, और अभिभावक वर्ग के रूप में हटाने से बच्चे के सदस्य चर को ठीक से हटा दिया जाता है (जो समझ में आता है , बेशक)।

मैं स्मृति रिसाव वी.एस. भीतर अनुरेखण इस्तेमाल किया है, और यह पता चलता है कि स्ट्रिंग है जो लीक समाप्त हो गया एक जब मैं Dialog बना दिया है और स्ट्रिंग निर्माता के लिए एक संदर्भ के रूप में पारित करने के लिए objString सेट बनाया गया था कि था।

धन्यवाद,
Jengerer

+0

(ओह, मेरी पिछली टिप्पणी ऑपरेटर प्राथमिकता पढ़ने में गलती से पीड़ित थी)। मुझे लगता है कि आपको और कोड दिखाना होगा। 'ओबीजे' की परिभाषा को देखते हुए और इसका आवंटन कैसे किया जाता है, यह अनुमान लगाना मुश्किल है कि क्या 'obj-> objString' सही ढंग से मुक्त हो जाएगा। –

+0

यह एक गड़बड़ की तरह दिखता है, इसलिए मैं अपनी टिप्पणी के साथ ओपी को अपडेट करने जा रहा हूं। – Jengerer

+1

क्या 'पॉपअप' का आभासी विनाशक है? –

उत्तर

8

आप जो देख रहे अपरिभाषित व्यवहार वास्तव में एक स्मृति रिसाव नहीं है -यह है। सी स्ट्रिंग के लिए स्मृति को हटा दिया गया है (कम से कम जहां तक ​​आप चिंतित हैं), लेकिन डेटा अभी भी तकनीकी रूप से सुलभ है। जब आप स्मृति को डिलीकेट करते हैं, तो स्मृति आमतौर पर मिटा नहीं जाती है, इसलिए डेटा अक्सर तब तक रहता है जब स्मृति को बाद के आवंटन द्वारा पुन: उपयोग नहीं किया जाता है।

इसे हटाए जाने के बाद डेटा पढ़ना अनिर्धारित व्यवहार है: आपको यह पता चल सकता है कि डेटा को हटा दिया गया था, आपको कचरा डेटा मिल सकता है, आप अपने प्रोग्राम को क्रैश कर सकते हैं, या आप अपनी हार्ड ड्राइव को भी मिटा सकते हैं (हालांकि यह नहीं है बहुत संभावना है)।

जब तक std::string ऑब्जेक्ट को ठीक से हटाया जा रहा है, तो उसके सी स्ट्रिंग प्रस्तुति के लिए उपयोग की जाने वाली किसी भी स्मृति को भी हटा दिया जाएगा। आपको इसके बारे में चिंता करने की ज़रूरत नहीं है।


संपादित: असल में यह पता चला है आपके वस्तु हो रही है क्योंकि माता पिता वर्ग Popup एक आभासी नाशक नहीं था नष्ट fulled नहीं किया गया। नतीजतन, subclass Dialog के लिए विनाशक नहीं बुलाया जा रहा था, इसलिए std::string उदाहरण के लिए विनाशक को बुलाया नहीं जा रहा था।

+0

यह समझ में आएगा, लेकिन मैंने विजुअल स्टूडियो की मेमोरी लीक डिटेक्शन प्रक्रिया का उपयोग किया (जो मूल रूप से सभी 'मॉलोक' और 'फ्री' कॉल का पालन करता है) और जब मैंने प्रोग्राम के अंत में मेमोरी रिसाव की जानकारी डाली, तो उस स्ट्रिंग इसी तरह के स्थान पर स्थित, दिखाया गया है कि ठीक तरह से हटाया नहीं जा रहा है। – Jengerer

3

समस्या std::string में सबसे अधिक संभावना नहीं है, लेकिन obj (जो भी प्रकार है) में। ध्यान दें कि आपने obj हटा दिया है, cppString नहीं।मेरा अनुमान है कि obj एक स्मार्ट पॉइंटर क्लास में objString स्टोर नहीं करता है और न ही यह अपने विनाशक में objString हटा देता है, और इसलिए आपके पास यह रिसाव है।

+0

'objString' एक नियमित स्ट्रिंग है, पॉइंटर नहीं, इसलिए इसे स्वचालित रूप से डिफ़ॉल्ट विनाशक द्वारा हटाया जाना चाहिए, नहीं? – Jengerer

+0

@Jengerer, आपने "const string *" टाइप करने के लिए objString से असाइन किया है, "कॉन्स्ट स्ट्रिंग" टाइप न करने के लिए, इसलिए यह एक पॉइंटर प्रकार होना चाहिए, जब तक कि आपने हमारे साथ अलग कोड साझा नहीं किया हो। –

+0

मेरा मतलब था कि ऑब्जेक्ट क्लास में, 'objString' एक' स्ट्रिंग 'प्रकार है और पॉइंटर नहीं है। जब मैंने इसे 'कॉन्स स्ट्रिंग *' पर असाइन किया, तो मैंने '& obj-> objString' किया, इसलिए मैंने पता लगाने के लिए ऑपरेटर का उपयोग किया। – Jengerer

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