c++ - هل "& s[0]" تشير إلى أحرف متجاورة في سلسلة std:: string؟




memcpy stdstring (4)

انها آمنة للاستخدام. أعتقد أن معظم الإجابات كانت صحيحة مرة واحدة ، لكن المعيار تغير. نقلاً عن المعيار C ++ 11 ، فإن المتطلبات العامة لـ basic_string [string.require] ، 21.4.1.5 ، تقول:

يتم تخزين الكائنات المشابهة في كائن basic_string بشكل متزامن. وهذا يعني أنه بالنسبة لأي كائن s Basic_string ، يجب أن يحتفظ بالهوية & * (s.begin () + n) == & * s.begin () + n بجميع قيم n مثل 0 <= n <s.size ().

قبل ذلك بقليل ، تقول أن جميع المتكررات عبارة عن تكرارات الوصول العشوائي. كلتا البتات تدعم استخدام سؤالك. (بالإضافة إلى ذلك ، يستخدم Stroustrup على ما يبدو في كتابه الجديد ؛))

من غير المحتمل أن يتم هذا التغيير في C ++ 11. يبدو أنني أتذكر أن نفس الضمانة قد أُضيفت بعد ذلك إلى المتجه ، والذي حصل أيضًا على مؤشر البيانات () ذي الفائدة المفيدة جدًا مع هذا الإصدار.

امل ان يساعد.

أقوم ببعض أعمال الصيانة وركض على شيء مثل ما يلي:

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 );

أعرف أن استخدام & s [0] سيكون آمنًا إذا كان std :: vector ، ولكن هل هذا استخدام آمن لسلسلة std ::؟


قد تعمل الشفرة ، ولكن من خلال الحظ أكثر من الحكم ، فإنها تضع افتراضات حول التنفيذ غير مضمونة. أقترح أن تحديد صلاحية الشفرة أمر غير ذي صلة ، في حين أنه لا فائدة من المضاعفات التي يمكن اختزالها بسهولة إلى:

std::string s( str ) ;

أو في حالة تعيين كائن std :: string موجود ، فقط:

s = str ;

ثم ترك std :: string نفسها تحدد كيفية تحقيق النتيجة. إذا كنت ستلجأ إلى هذا النوع من الهراء ، فإنك قد لا تستخدم سلسلة std :: وتلتزم بها لأنك تعيد تقديم كل المخاطر المرتبطة بالسلاسل C.


من الناحية الفنية ، لا ، حيث أن std::string غير مطلوب لتخزين محتوياته بشكل متقارب في الذاكرة.

ومع ذلك ، في جميع التطبيقات تقريبا (كل ما أدركه من تنفيذ) ، يتم تخزين المحتويات بشكل متقارب وهذا من شأنه أن "يعمل".


هذا بشكل عام غير آمن ، بغض النظر عن ما إذا كان يتم تخزين تسلسل السلسلة الداخلية في الذاكرة بشكل مستمر أم لا. قد يكون هناك العديد من تفاصيل التنفيذ الأخرى المتعلقة بكيفية تخزين التسلسل std::string بواسطة كائن std::string ، إلى جانب الاستمرارية.

قد تكون المشكلة العملية الحقيقية في هذا ما يلي. التسلسل المتحكم فيه لسلسلة std::string غير مطلوب ليتم تخزينه كسلسلة غير مُنهية. ومع ذلك ، من الناحية العملية ، تختار العديد من تطبيقات (معظم؟) لتكبير المخزن المؤقت الداخلي بواسطة 1 وتخزين التسلسل كسلسلة صفر إنهاء على أية حال لأنه يبسّط تنفيذ الأسلوب c_str() : فقط إرجاع مؤشر إلى المخزن المؤقت الداخلي و انتهيت.

لا يتم نسخ التعليمات البرمجية التي اقتبستها في سؤالك عن أي جهد لإنهاء البيانات صفر في المخزن المؤقت الداخلي. من المحتمل جدا أنه ببساطة لا يعرف ما إذا كان إنهاء الصفر ضروريًا لتنفيذ هذا std::string . من المحتمل جداً أنها تعتمد على المخزن المؤقت الداخلي المملوء بالأصفار بعد استدعاء resize ، لذا فإن الحرف الزائد المخصص للنهاية صفر بواسطة التطبيق يتم ضبطه مسبقًا بشكل مريح على صفر. كل هذا عبارة عن تفاصيل التنفيذ ، وهذا يعني أن هذه التقنية تعتمد على بعض الافتراضات الهشة.

وبعبارة أخرى ، في بعض التطبيقات ، قد يتعين عليك استخدام strcpy ، وليس memcpy لفرض البيانات في التسلسل المتحكم فيه مثل ذلك. بينما في بعض التطبيقات الأخرى عليك استخدام memcpy وليس strcpy .





c++03