موضع جديد وحذف لغز
في لغة C، عند تخصيص الذاكرة مع عامل الموضع الجديد، تظهر معضلة فيما يتعلق بالطريقة المناسبة لإلغاء التخصيص تلك الذاكرة. دعنا نستكشف حلين محتملين:
الحل 1:
const char* charString = "Hello, World";
void *mem = ::operator new(sizeof(Buffer) strlen(charString) 1);
Buffer* buf = new(mem) Buffer(strlen(charString));
delete (char*)buf;
يحاول هذا الحل حذف الذاكرة المخصصة كمؤشر للأحرف. ومع ذلك، هذا الأسلوب غير صحيح لأنه لا يتعامل بشكل صحيح مع مدمر الكائن أو إلغاء تخصيص الذاكرة الأولية.
الحل 2:
const char* charString = "Hello, World";
void *mem = ::operator new(sizeof(Buffer) strlen(charString) 1);
Buffer* buf = new(mem) Buffer(strlen(charString));
delete buf;
يحاول هذا الحل أيضًا حذف الذاكرة المخصصة، ولكنه يستدعي مباشرة عامل الحذف على مؤشر Buffer*. قد ينجح هذا إذا تم تخصيص الذاكرة باستخدام عامل التشغيل الجديد العادي. ومع ذلك، بما أنه تم استخدام موضع جديد، فإن هذا الأسلوب غير صحيح أيضًا.
الحل الصحيح:
الطريقة الصحيحة لتحرير الذاكرة المخصصة هي:
buf->~Buffer();
::operator delete(mem);
يستدعي هذا الحل بشكل صريح المدمر لكائن Buffer (buf->~Buffer()) ثم يقوم بإلغاء تخصيص الذاكرة الأولية باستخدام وظيفة حذف عامل التشغيل (::operatordelet( mem)).
الفرق الحاسم هنا هو أنه عند استخدام الموضع الجديد، يجب استدعاء وظيفة الحذف الخاصة بالمشغل مباشرةً لتحرير الذاكرة الأولية. لن تؤدي محاولة حذف المؤشر الذي تم الحصول عليه من عامل التشغيل الجديد إلى استدعاء أداة التدمير بشكل صحيح أو إلغاء تخصيص الذاكرة بالكامل.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3