لماذا لا يتسبب WSTRING :: C_STR في تسرب الذاكرة إذا لم يتم حذفه بشكل صحيح
-
26-09-2019 - |
سؤال
مقطع الرمز 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 * يعود.