2012-04-04 17 views
45

निम्नलिखित सी ++ कोड अच्छी तरह से गठित है:std :: स्ट्रिंग :: c_str() और temporaries

void consumer(char const* p) 
{ 
    std::printf("%s", p); 
} 

std::string random_string_generator() 
{ 
    // returns a random std::string object 
} 

consumer(random_string_generator().c_str()); 

समस्या मैं इसके साथ है, यह है कि अस्थायी std :: स्ट्रिंग वस्तु बनाने और लेने के बाद c_str() पॉइंटर, std :: स्ट्रिंग ऑब्जेक्ट को नष्ट होने से रोकता है (या शायद मैं गलत हूं?)। यदि आप सब कुछ के बावजूद ठीक है, तो क्या आप मुझे मानक पर इंगित कर सकते हैं। यह काम करता है, जब मैं जी ++ के साथ परीक्षण करता हूं।

उत्तर

56

सूचक स्मृति स्ट्रिंग वस्तु द्वारा बनाए रखा करने के लिए std::string::c_str() अंक लौट आए। यह तब तक वैध रहता है जब तक गैर-कॉन्स फ़ंक्शन स्ट्रिंग ऑब्जेक्ट पर नहीं कहा जाता है, या स्ट्रिंग ऑब्जेक्ट नष्ट हो जाता है। जिस स्ट्रिंग ऑब्जेक्ट के बारे में आप चिंतित हैं वह एक अस्थायी है। यह पूर्ण अभिव्यक्ति के अंत में नष्ट हो जाएगा, पहले और के बाद नहीं। आपके मामले में, पूर्ण अभिव्यक्ति का अंत consumer पर कॉल करने के बाद है, इसलिए आपका कोड सुरक्षित है। ऐसा नहीं होगा अगर consumer बाद में इसका उपयोग करने के विचार के साथ कहीं भी सूचक को बचाया।

सी ++ 98 के बाद से अस्थायी लोगों का जीवनकाल सख्ती से परिभाषित किया गया है। इससे पहले, यह कंपाइलर के आधार पर भिन्न था, और आपके पास कोड कोड जी ++ (पूर्व 1995, लगभग — जी ++ के साथ काम नहीं करता था, जब मानक समिति ने इसे वोट दिया था)। (तब कोई std::string नहीं था, लेकिन एक ही समस्या किसी भी उपयोगकर्ता लिखित स्ट्रिंग क्लास को प्रभावित करती है।)

18

अस्थायी std::string के जीवन सिर्फ बिंदु से परे फैली हुई जहां consumer रिटर्न, तो यह consumer के भीतर से कि स्ट्रिंग सीधे पर कुछ भी उपयोग करने के लिए सुरक्षित है। ठीक है उस मान को स्टोर करना है जो c_str रिटर्न देता है और बाद में इसका उपयोग करने का प्रयास करता है (अस्थायी नष्ट हो जाएगा, और हम केवल अनुमान लगा सकते हैं कि आप सूचक के दूसरे छोर पर क्या पाएंगे)।

+1

क्या आप सी ++ 03 या सी ++ 11 मानक के संबंध में संकेत दे सकते हैं? – user1095108

+3

अस्थायी जीवनकाल §12.2 में परिभाषित किया गया है। (धारा 12 हकदार "विशेष सदस्य कार्यों" जो वास्तव में नहीं है, जहां आप temporaries के जीवन भर के लिए देखने के लिए उम्मीद थी है, लेकिन वह कहाँ है कि है।) –

+0

@ user1095108 और समारोह तर्क के जीवनकाल § से प्राप्त किया जा सकता 3.2.2 और §3.7.2 सी ++ 03 मानक में। – juanchopanza

5

फ़ंक्शन random_string_generator() द्वारा अस्थायी रूप से लौटाया गया उपभोक्ता() फ़ंक्शन सुरक्षित रूप से उपयोग किया जा सकता है।

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