لماذا لا يتسبب WSTRING :: C_STR في تسرب الذاكرة إذا لم يتم حذفه بشكل صحيح

StackOverflow https://stackoverflow.com/questions/3424957

سؤال

مقطع الرمز 1:

wchar_t *aString() 
{
     wchar_t *str = new wchar[5];
     wcscpy(str, "asdf\0");
     return str;
}
wchar_t *value1 = aString();

مقطع رمز 2

wstring wstr = L"a value";
wchar_t *value = wstr.c_str();

إذا لم يتم حذف القيمة من الشريحة 2 ، فلن يحدث تسرب الذاكرة. ومع ذلك ، إذا لم يتم حذف Value1 من قطاع الرمز 1 ، فهناك تسرب للذاكرة. الرمز الداخلي لـ WSTRING :: C_STR يبدو كما هو بالنسبة لي.

هل كانت مفيدة؟

المحلول

قاعدة مهمة: يجب استخدامك delete على أي شيء تم إنشاؤه بواسطة new, ، ويجب ألا تحذف أي شيء آخر.

wstr.c_str() يعيد مؤشر إلى مخزن مؤقت يديره wstring هدف. سيتم تعديله عند تدمير السلسلة ، وبعد ذلك لن يكون المؤشر صالحًا. استخدام delete على هذا خطأ. سيتم أيضًا إبطال المؤشر إذا قمت بتعديل السلسلة.

aString() إرجاع مؤشر إلى مخزن مؤقت تم إنشاؤه باستخدام new[], ، لذلك يجب عليك حذفه عند الانتهاء منه (باستخدام delete[], ، كثيرا new[]). هذا معرض للخطأ ، وهذا هو السبب في أنه من الأفضل استخدام فصول إدارة الموارد (مثل string, wstring, ، الحاويات والمؤشرات الذكية) بدلاً من المرور حول المؤشرات الأولية على أمل أن تعامل بشكل صحيح.

نصائح أخرى

لان c_str() يعيد لك مؤشر إلى التمثيل الداخلي لـ wstring. يحتفظ الفصل بالتحكم في البيانات التي تحتوي عليها.

مأخوذة من basic_string::c_str() وثائق من MSDN:

لا ينبغي أن تكون السلسلة على غرار C التي تم إرجاعها تم تعديله ، لأن هذا يمكن أن يبطل المؤشر إلى السلسلة ، أو تم حذفه ، لأن السلسلة لها عمر محدود ومملوكة لسلسلة الفئة.

سأخرج على أحد الأطراف وأقول إن wstring ليس WCHAR_T ، ولكن بدلاً من ذلك فئة لديها مشغل لإعادة WCHAR_T *، لذلك في مدمرة WSTRING ، من المحتمل أن تحرر نسختها الخاصة من WCHAR_T * يعود.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top