c++ - क्या "& s[0]" std:: स्ट्रिंग में संगत वर्णों को इंगित करता है?




memcpy stdstring (4)

मैं कुछ रखरखाव का काम कर रहा हूं और निम्न की तरह कुछ चला गया:

std::string s;
s.resize( strLength );  
// strLength is a size_t with the length of a C string in it. 

memcpy( &s[0], str, strLength );

मुझे पता है कि एस और 0 [0] सुरक्षित होगा अगर यह std :: वेक्टर था, लेकिन क्या यह std :: string का सुरक्षित उपयोग है?


एक std :: स्ट्रिंग का आवंटन C ++ 98/03 मानक के तहत संगत होने की गारंटी नहीं है, लेकिन सी ++ 11 इसे बल देता है। अभ्यास में, न तो मैं और न ही हर्ब सटर को एक कार्यान्वयन के बारे में पता है जो संगत भंडारण का उपयोग नहीं करता है।

ध्यान दें कि &s[0] चीज़ हमेशा सी -+ 11 मानक द्वारा काम करने की गारंटी दी जाती है, यहां तक ​​कि 0-लंबाई स्ट्रिंग केस में भी। यदि आपने str.begin() या &*str.begin() , तो यह गारंटी नहीं दी जाएगी, लेकिन &s[0] मानक operator[] को परिभाषित करता operator[] :

रिटर्न : *(begin() + pos) यदि pos < size() , अन्यथा मूल्य charT() साथ प्रकार T किसी ऑब्जेक्ट का संदर्भ; संदर्भित मान संशोधित नहीं किया जाएगा

जारी है, data() को इस प्रकार परिभाषित किया गया है:

रिटर्न: एक पॉइंटर p जैसे कि p + i == &operator[](i) प्रत्येक के लिए [0,size()]

(सीमा के दोनों सिरों पर स्क्वायर ब्रैकेट्स देखें)

नोटिस : प्री-मानकीकरण सी ++ 0 एक्स ने गारंटी नहीं दी है &s[0] शून्य-लंबाई तारों के साथ काम करने के लिए (वास्तव में, यह स्पष्ट रूप से अपरिभाषित व्यवहार था), और इस उत्तर के पुराने संशोधन ने इसे समझाया; इसे बाद के मानक ड्राफ्ट में तय किया गया है, इसलिए उत्तर तदनुसार अपडेट किया गया है।


कोड काम कर सकता है, लेकिन निर्णय से भाग्य से अधिक, यह कार्यान्वयन के बारे में धारणा करता है जो गारंटी नहीं है। मेरा सुझाव है कि कोड की वैधता निर्धारित करना अप्रासंगिक है, जबकि यह जटिलता पर एक व्यर्थ है जो आसानी से कम हो जाता है:

std::string s( str ) ;

या यदि किसी मौजूदा std :: स्ट्रिंग ऑब्जेक्ट को असाइन करना है, तो बस:

s = str ;

और फिर std :: स्ट्रिंग स्वयं निर्धारित करें कि परिणाम कैसे प्राप्त करें। यदि आप इस तरह के बकवास का सहारा ले रहे हैं, तो आप std :: स्ट्रिंग का उपयोग नहीं कर सकते हैं और तब से चिपक सकते हैं क्योंकि आप सी स्ट्रिंग से जुड़े सभी खतरों को पुन: पेश कर रहे हैं।


पाठकों को ध्यान रखना चाहिए कि 200 9 में इस सवाल से पूछा गया था, जब सी ++ 03 मानक वर्तमान प्रकाशन था। यह उत्तर मानक के उस संस्करण पर आधारित है, जिसमें std::string s को संगत भंडारण का उपयोग करने की गारंटी नहीं है । चूंकि इस सवाल को किसी विशेष प्लेटफॉर्म (जीसीसी की तरह) के संदर्भ में नहीं पूछा गया था, इसलिए मैं ओपी के प्लेटफार्म के बारे में कोई धारणा नहीं करता - विशेष रूप से, मौसम या string लिए यह विरोधाभासी भंडारण का उपयोग नहीं करता है।

कानूनी? शायद शायद नहीं। सुरक्षित? शायद, लेकिन शायद नहीं। अच्छा कोड? खैर, चलो वहाँ नहीं जाते ...

क्यों न करें:

std::string s = str;

... या:

std::string s(str);

... या:

std::string s;
std::copy( &str[0], &str[strLen], std::back_inserter(s));

... या:

std::string s;
s.assign( str, strLen );

?


यह आम तौर पर सुरक्षित नहीं है , भले ही आंतरिक स्ट्रिंग अनुक्रम लगातार स्मृति में संग्रहीत किया गया हो या नहीं। निरंतरता के अलावा std::string ऑब्जेक्ट द्वारा नियंत्रित अनुक्रम को संग्रहीत करने के तरीके से संबंधित कई अन्य कार्यान्वयन विवरण हो सकते हैं।

इसके साथ एक असली व्यावहारिक समस्या निम्नलिखित हो सकती है। std::string नियंत्रित अनुक्रम को शून्य-समाप्त स्ट्रिंग के रूप में संग्रहीत करने की आवश्यकता नहीं है। हालांकि, व्यावहारिक रूप से, कई (अधिकांश?) कार्यान्वयन आंतरिक बफर को 1 से बढ़ाकर चुनते हैं और अनुक्रम को शून्य-समाप्त स्ट्रिंग के रूप में संग्रहीत करते हैं क्योंकि यह c_str() विधि के कार्यान्वयन को सरल c_str() : केवल आंतरिक बफर पर एक सूचक लौटाएं और आप कर चुके हैं।

आपके प्रश्न में उद्धृत कोड आंतरिक बफर में डेटा की प्रतिलिपि शून्य-समाप्त करने का कोई प्रयास नहीं करता है। काफी संभवतः यह नहीं जानता कि std::string कार्यान्वयन के लिए शून्य-समाप्ति आवश्यक है या नहीं। काफी संभवतः यह कॉल करने के बाद कॉल के बाद ज़ीरो से भरे आंतरिक बफर पर निर्भर करता है, इसलिए कार्यान्वयन द्वारा शून्य टर्मिनेटर के लिए आवंटित अतिरिक्त वर्ण आसानी से शून्य पर पूर्व-निर्धारित होता है। यह सब एक कार्यान्वयन विस्तार है, जिसका अर्थ है कि यह तकनीक कुछ नाजुक धारणाओं पर निर्भर करती है।

दूसरे शब्दों में, कुछ कार्यान्वयन में, आपको शायद strcpy का उपयोग करना होगा, डेटा को नियंत्रित अनुक्रम में डेटा को मजबूर करने के लिए memcpy नहीं। जबकि कुछ अन्य कार्यान्वयन में आपको memcpy का उपयोग करना होगा और strcpy नहीं करना होगा।





c++03