2011-08-22 9 views
12

मैं सी ++ के तारों के साथ काफी नौसिखिया हूं इसलिए निम्न पैटर्न थोड़ा भाग्यशाली हो सकता है। मैं एक बड़े सिस्टम के साथ एकीकरण परीक्षण शुरू करने से पहले मैंने लिखा कुछ कोड की समीक्षा कर रहा हूं। मैं क्या जानना चाहता हूं कि यह सुरक्षित है, या यदि यह स्मृति को लीक करने के लिए प्रवण होगा?एक सी ++ std :: स्ट्रिंग ऑब्जेक्ट को स्मृति रिसाव से सुरक्षित कर रहा है?

string somefunc(void) { 
    string returnString; 
    returnString.assign("A string"); 
    return returnString; 
} 

void anotherfunc(void) { 
    string myString; 
    myString.assign(somefunc()); 
    // ... 
    return; 
} 

समझ रहा है कि returnString का मूल्य एक नई वस्तु myString को सौंपा गया है और उसके बाद returnString वस्तु कॉल somefunc को हल करने के भाग के रूप को नष्ट कर दिया जाता है। भविष्य में किसी बिंदु पर जब MyString गुंजाइश से बाहर हो जाता है, तो यह भी नष्ट हो जाता है।

मैं आमतौर पर myString() में myString के लिए एक पॉइंटर पास कर देता था और सीधे MyString के मानों को सौंपा गया था, लेकिन मैं अपने कोड में थोड़ा स्पष्ट होने का प्रयास कर रहा हूं (और साइड इफेक्ट फ़ंक्शन शैली पर निर्भर करता हूं)।

+0

पहले फ़ंक्शन में, आप शायद "वापसी स्ट्रिंग (" एक स्ट्रिंग ") कर सकते हैं;" और एक ही परिणाम है। – luiscubal

+0

@luiscubal यह समस्या को स्पष्ट करने के लिए एक सरलीकृत उदाहरण है। – Stephen

+2

@luiscubal भी 'वापसी' एक स्ट्रिंग "; 'ठीक है क्योंकि std :: स्ट्रिंग सी तारों के साथ रचनात्मक है। – log0

उत्तर

10

हाँ, एक string इस तरह से लौटने (मूल्य) के द्वारा सुरक्षित है, यद्यपि मैं इसे इस तरह से बताए पसंद करेंगे:,

string myString = somefunc(); 

यह पढ़ने में आसान है और यह भी अधिक कुशल है (एक खाली स्ट्रिंग के निर्माण को सहेज रहा है, जिसे अगली कॉल द्वारा assign पर ओवरराइट किया जाएगा)।

std::string अपनी याददाश्त का प्रबंधन करता है, और यह ठीक से कॉपी कन्स्ट्रक्टर और असाइनमेंट ऑपरेटर लिखा है, इसलिए इस तरह तारों का उपयोग करना सुरक्षित है।

2

हां, यह (कम से कम सामान्य रूप से) सुरक्षित है। लगभग किसी भी उचित स्ट्रिंग क्लास के सबसे बुनियादी योगदानों में से एक मूल मूल्य की तरह कार्य करने की क्षमता है जिसके लिए सामान्य असाइनमेंट, रिटर्न इत्यादि, "बस काम करें"।

return returnString 

करके

7

हाँ आप स्ट्रिंग के copy constructor लागू कर रहे हैं।

myString.assign(somefunc() /*somefunc()'s return becomes temporary*/); 

यह बदले आवंटित करने के लिए पारित किया और असाइन द्वारा प्रयोग किया जाता में एक प्रदर्शन करने के लिए है: जो ") (somefunc" अस्थायी (उर्फ rvalue) में returnString की * एक प्रति है कि की जगह लेता है बुला अभिव्यक्ति में प्रदर्शन MyString में कॉपी करें।

तो आपके मामले में, स्ट्रिंग की कॉपी कन्स्ट्रक्टर गहरी प्रति की गारंटी देता है और कोई मेमोरी लीक सुनिश्चित नहीं करता है।

* ध्यान दें कि यह एक वास्तविक गहरी प्रतिलिपि हो सकती है या नहीं, प्रतिलिपि निर्माता का व्यवहार कार्यान्वयन विशिष्ट है। कुछ स्ट्रिंग लाइब्रेरी कॉपी-ऑन-राइट को कार्यान्वित करते हैं जिसमें वास्तव में आवश्यक होने तक कॉपीिंग को रोकने के लिए कुछ आंतरिक बहीखाता होती है।

+1

असल में, क्या एक गहरी प्रतिलिपि की जाती है या नहीं, आप पूरी तरह से विशिष्ट मानक लाइब्रेरी कार्यान्वयन के लिए उपयोग कर रहे हैं। जीसीसी गाय का उपयोग कर रहा है, इसलिए कॉपी कन्स्ट्रक्टर बस काउंटर को बढ़ाने का तात्पर्य है। –

+0

@ मैथियू अच्छा बिंदु मैंने अपना जवाब स्पष्ट किया। धन्यवाद। –

5

आप पूरी तरह से सुरक्षित हैं क्योंकि आप मूल्य से स्ट्रिंग वापस कर रहे हैं, जहां स्ट्रिंग "प्रतिलिपि बनाई जाएगी", और संदर्भ के अनुसार नहीं। यदि आप std::string & वापस लौटाना चाहते थे, तो आप इसे गलत कर रहे होंगे, क्योंकि आपके पास एक खतरनाक संदर्भ होगा। कुछ कंपाइलर, यहां तक ​​कि रिटर्न वैल्यू ऑप्टिमाइज़ेशन कर सकते हैं, जो वास्तव में स्ट्रिंग पर स्ट्रिंग को कॉपी नहीं करेगा। अधिक जानकारी के लिए this post देखें।

0

जैसा कि आपने कहा था कि returnStringsomefunc के अंदर बनाया गया है और फ़ंक्शन लौटने पर प्रतिलिपि वापस दी जाती है। यह पूरी तरह से सुरक्षित है।

आप क्या चाहते हैं myString से somefunc (सूचक का उपयोग न करें) का संदर्भ देना है। यह पूरी तरह से स्पष्ट हो जाएगा:

void somefunc(string& myString) { 
    myString.assign("A string"); 
} 

void anotherfunc(void) { 
    string myString; 
    somefunc(myString); 
    // ... 
    return; 
} 
+1

यह आमतौर पर कंपेलरों द्वारा किए गए रिटर्न वैल्यू ऑप्टिमाइज़ेशन को छोड़ देता है, इसलिए यह कोई सुधार नहीं है। –

+0

@ बो पर्सन मैंने प्रदर्शन सुधार के बारे में कभी बात नहीं की। – log0

+0

'आप जो चाहते हैं वह है ...' आप ऐसा क्यों कहते हैं? मैं आपके कोड पर जो कुछ कर रहा हूं उसके बारे में थोड़ा सा फायदा देखता हूं। –

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