2010-04-29 9 views
7

तो, मैं सी ++ काम में स्ट्रिंग अक्षर कैसे बेहतर समझना चाहता हूं। मैं ज्यादातर परिस्थितियों से चिंतित हूं जहां आप एक सूचक के लिए एक स्ट्रिंग अक्षर का पता आवंटित कर रहे हैं, और इसे चारों ओर पास कर रहे हैं। उदाहरण के लिए:सी ++ स्ट्रिंग लिटरेल्स कितने सुरक्षित और भरोसेमंद हैं?

char* advice = "Don't stick your hands in the toaster."; 

अब कहें कि मैं प्रोग्राम की अवधि के लिए पॉइंटर्स की प्रतिलिपि बनाकर बस इस स्ट्रिंग को पास करता हूं। निश्चित रूप से, यह शायद एक अच्छा विचार नहीं है, लेकिन मैं उत्सुक हूं कि वास्तव में दृश्यों के पीछे क्या चल रहा है।

एक और उदाहरण के लिए, मान लीजिए कि हम एक समारोह है कि एक स्ट्रिंग शाब्दिक रिटर्न करते हैं:

char* foo() 
{ 
    // function does does stuff 
    return "Yikes!"; // somebody's feeble attempt at an error message 
} 

अब कहते हैं कि इस समारोह बहुत बार कहा जाता है की सुविधा देता है, और स्ट्रिंग शाब्दिक केवल समय के बारे में आधे यह कहा जाता है प्रयोग किया जाता है :

// situation #1: it's just randomly called without heed to the return value 
foo(); 

// situation #2: the returned string is kept and used for who knows how long 
char* retVal = foo(); 

पहली स्थिति में, वास्तव में क्या हो रहा है? क्या स्ट्रिंग अभी बनाई गई है लेकिन इसका उपयोग नहीं किया गया है, और कभी भी बर्बाद नहीं किया गया है?

दूसरी स्थिति में, जब तक उपयोगकर्ता को इसकी आवश्यकता होती है तब तक स्ट्रिंग को बनाए रखा जा रहा है? क्या होता है जब इसकी आवश्यकता नहीं होती है ... क्या उस स्मृति को मुक्त कर दिया जाएगा (अब उस जगह को कुछ भी नहीं मानते हैं)?

मुझे गलत मत समझो, मैं इस तरह स्ट्रिंग अक्षर का उपयोग करने की योजना नहीं बना रहा हूं। मैं अपने तारों को चेक में रखने के लिए एक कंटेनर का उपयोग करने की योजना बना रहा हूं (शायद std :: string)। मैं ज्यादातर यह जानना चाहता हूं कि क्या ये स्थितियां स्मृति प्रबंधन या दूषित डेटा के लिए समस्याएं पैदा कर सकती हैं।

+8

सी ++ स्ट्रिंग अक्षर पूरी तरह से सुरक्षित और भरोसेमंद हैं। यह प्रोग्रामर हैं जो स्ट्रिंग अक्षर का उपयोग करते हैं जो सुरक्षित और भरोसेमंद नहीं हैं। –

+0

यही वह है जो मैं सोच रहा था; मुझे बस मुझे लगता है कि आश्वासन की आवश्यकता है। धन्यवाद। :) –

उत्तर

22

स्ट्रिंग-लिटरल का प्रकार const char[N] है (जहां N लंबाई + 1 है) और स्थिर रूप से आवंटित हैं। आपको स्मृति समस्याओं के बारे में चिंता करने की ज़रूरत नहीं है; यदि आपके प्रोग्राम में एक स्ट्रिंग का उपयोग किया जाता है तो यह सब आपके लिए संभाला जाता है, और प्रोग्राम मेमोरी में कहीं भी रहता है (आमतौर पर केवल पढ़ने के लिए)।

है यही कारण है कि, इन "एक ही" कर रहे हैं:

static const char str[] = "a string"; 
"a string" 

जब आप शाब्दिक एक स्ट्रिंग को इंगित, आप सरणी में पहला वर्ण ओर इशारा करते हैं। वास्तव में, क्योंकि प्रकार const char[] है, यह const char* के माध्यम से इसे इंगित करने के लिए केवल सुरक्षित है। स्ट्रिंग शाब्दिक से char* का रूपांतरण बहिष्कृत और असुरक्षित है।

// the "same" 
static const char str[] = "a string"; 
const char* strPtr = str; // decays 

const char* s1 = "a string"; 
char* s2 = "a string"; // allowed, implicit const_cast 

*s1 = 'A'; // not allowed, it's const 
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior) 
+5

"स्ट्रिंग शाब्दिक से char * में रूपांतरण को बहिष्कृत किया गया है, और असुरक्षित है।" हाँ। यदि आप कहीं ऐसा करते हैं तो लिखने योग्य-स्ट्रिंग्स की आवश्यकता होती है। वैसे भी, ऐसा मत करो। – Joshua

+1

हाँ, विस्तार से कॉन्स पहलू को समझाने के लिए धन्यवाद। मुझे पता था कि वे स्थिर थे, लेकिन मुझे लगा कि मैं उन लोगों को स्पष्टीकरण छोड़ दूंगा जो उन्हें बेहतर से समझते हैं :) –

+2

आपने यह सब कहा है, जहां तक ​​मैं कह सकता हूं। –

1

सबसे पहले,, स्थिरांक के रूप में foo की वापसी मूल्य की घोषणा क्योंकि स्ट्रिंग शाब्दिक स्थिरांक कि खतरनाक "अपरिभाषित व्यवहार" पैदा करने के बिना नहीं बदला जा सकता है। इसके बाद यह किसी भी पॉइंटर्स को मजबूर करेगा जो फू के रिटर्न वैल्यू का उपयोग कॉन्स के रूप में घोषित किया जा सकता है, और संभावित रूप से क्षति को सीमित कर सकता है (आमतौर पर अनजाने में) किया जा सकता है। स्ट्रिंग अक्षर एक बाइनरी निष्पादन योग्य के 'टेक्स्ट' क्षेत्र में संग्रहीत होते हैं - वे रन टाइम पर इस प्रकार नहीं बनाए जाते हैं।

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