2010-08-06 15 views
5

कोड खंड 1 नहीं:क्यों wstring नहीं है :: c_str एक स्मृति रिसाव के कारण अगर ठीक से नष्ट कर दिया

wchar_t *aString() 
{ 
    wchar_t *str = new wchar[5]; 
    wcscpy(str, "asdf\0"); 
    return str; 
} 
wchar_t *value1 = aString(); 

कोड खंड 2

wstring wstr = L"a value"; 
wchar_t *value = wstr.c_str(); 

कोड खंड 2 से मूल्य तो नष्ट नहीं किया जाता है तो एक स्मृति रिसाव नहीं होता है। हालांकि, यदि कोड सेगमेंट 1 से वैल्यू 1 हटाया नहीं गया है तो मेमोरी रिसाव है। Wstring :: c_str का आंतरिक कोड मेरे जैसा ही दिखता है।

उत्तर

11

एक महत्वपूर्ण नियम: आपको का उपयोग new द्वारा बनाई गई किसी भी चीज़ पर करना चाहिए, और आपको कुछ और नहीं हटाना चाहिए।

wstr.c_str()wstring ऑब्जेक्ट द्वारा प्रबंधित एक बफर को एक सूचक देता है। जब स्ट्रिंग नष्ट हो जाती है तो इसे हटा दिया जाएगा, जिसके बाद सूचक अब मान्य नहीं होगा। इस पर delete का उपयोग करना गलत है। यदि आप स्ट्रिंग को संशोधित करते हैं तो पॉइंटर को भी अमान्य कर दिया जाएगा।

aString() एक बफर कि new[] का उपयोग कर बनाया गया था करने के लिए एक सूचक देता है, इसलिए जब आप (delete[] का उपयोग कर, new[] मैच के लिए) इसके साथ समाप्त किया है आपको उसे हटाना होगा। यह त्रुटि-प्रवण है, यही कारण है कि कच्चे पॉइंटर्स के चारों ओर गुजरने के बजाय संसाधनों के प्रबंधन वर्गों (जैसे string, wstring, कंटेनर और स्मार्ट पॉइंटर्स) का उपयोग करना बेहतर अभ्यास है और उम्मीद है कि उनका सही ढंग से इलाज किया जाता है।

+1

टाइपो: "जब स्ट्रिंग नष्ट हो जाती है, जिसके बाद पॉइंटर * अब अमान्य नहीं होगा *" - अब मान्य नहीं होना चाहिए * या * अमान्य * –

+0

@ बेन: धन्यवाद, पहले ही तय हो गया है। –

1

मैं एक अंग पर बाहर जाने जा रहा हूं और कहता हूं कि एक wstring wchar_t नहीं है, बल्कि इसके बजाय एक वर्ग जिसके पास ऑपरेटर है wchar_t *, तो wstring के विनाशक में, यह संभवतः अपने आप को मुक्त करता है wchar_t * की प्रतिलिपि।

+0

यह ऑपरेटर नहीं है, यह एक स्पष्ट फ़ंक्शन कॉल 'cstr() 'है। यह मानक में सबसे अधिक उपयोग किए जाने वाले वर्गों में से एक है, मैं वास्तव में बहुत चौंक गया हूं कि उच्चतम मतदान वाला उत्तर इसके बारे में अनुमान लगा रहा है। –

+0

मैंने एक ऐसी कंपनी में लंबे समय तक काम किया है जिसकी एसटीएल ('यहां लिखी गई' मानसिकता नहीं है) के व्यापक गोद लेने से पहले अपनी स्वयं की स्ट्रिंग कक्षाएं हैं, इसलिए सालों से मैंने जो कुछ भी उपयोग किया है। –

2

क्योंकि c_str() आपको wstring के आंतरिक प्रतिनिधित्व के लिए एक सूचक देता है। कक्षा इसमें मौजूद डेटा का नियंत्रण रखती है।

2

basic_string::c_str()documentation from MSDN से लिया:

लौटे सी शैली स्ट्रिंग नहीं संशोधित किया जाना चाहिए, इस के रूप में स्ट्रिंग के लिए सूचक गलत हो सकते हैं, या नष्ट कर दिया, के रूप में स्ट्रिंग है एक सीमित जीवनकाल और वर्ग स्ट्रिंग के स्वामित्व में है।

+0

वैसे हाँ ... c_str का रिटर्न प्रकार कॉन्स char */wchar_t * है – monksy

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