سؤال

لدي هيكل مثل هذا:

class Items 
{
private:
    struct item
    {
        unsigned int a, b, c;
    };
    item* items[MAX_ITEMS];
}

لنفترض أنني أردت "حذف" عنصر ما، كما يلي:

items[5] = NULL;

وقمت بإنشاء عنصر جديد في نفس المكان لاحقًا:

items[5] = new item;

هل سأظل بحاجة إلى الاتصال delete[] لتنظيف هذا؟أو لن تكون هناك حاجة لهذا منذ حدود المصفوفة items[] معروفة قبل تجميع؟

هل تعيين هذا المؤشر على NULL صالح أم يجب أن أتصل بالحذف هناك؟

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

المحلول

وتحتاج إلى استدعاء delete قبل تعيين إلى NULL. (تعيين إلى NULL غير مطلوب، فإنه يساعد فقط تقليل الأخطاء إذا حاولت عن طريق الخطأ dereference المؤشر بعد حذفها.)

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

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

نصائح أخرى

وكما أشار كلوج خارج، وكنت تسرب الكائن في مؤشر 5 من هذا القبيل. ولكن هذا واحد يبدو حقا مثل يجب عدم القيام بذلك يدويا ولكن استخدام فئة حاوية داخل Item. إذا كنت لا تحتاج بالفعل لتخزين هذه الكائنات item على المؤشرات، واستخدام std::vector<item> بدلا من أن مجموعة من المؤشرات MAX_ITEMS. يمكنك دائما إدراج أو محو عناصر المتجه في وسط وكذلك إذا كنت في حاجة إليها.

في حال كنت بحاجة لتخزين الكائنات مثل مؤشرات (عادة إذا البنية item هي متعددة الأشكال في الواقع، خلافا لما حدث في المثال الخاص بك)، يمكنك استخدام دفعة :: ptr_vector <البند> من <لأ href = "HTTP: // شبكة الاتصالات العالمية. boost.org/doc/libs/1_37_0/libs/ptr_container/doc/ptr_container.html "يختلط =" نوفولو noreferrer "> Boost.PtrContainer بدلا من ذلك.

مثال:

class Items {
private:
    struct item {
        unsigned int a, b, c;
    };
    std::vector<item> items;
}

if (items.size() > 5) // (just to ensure there is an element at that position)
    items.erase(items.begin() + 5); // no need to use operator delete at all

لحذف استخدام البند:

وحذف العناصر [5]؛

وبعد حذف هذا البند فإنه من المستحسن أن تعيين مؤشر المحذوفة إلى NULL، لذلك سوف لا يكون لديك خطأ إذا كنت في وقت لاحق حذفه مرة أخرى عن طريق الخطأ.

والعناصر [5] = NULL

<اقتباس فقرة>   

ويقول أردت أن 'حذف' عنصر، كما يلي:

     <اقتباس فقرة>     

والعناصر [5] = NULL؛

  

وأنا أعرف القليل Visual Basic ولكن أن رائحة مثل لغة البرمجة ل Visual Basic، لأن "تعيين = بلا" (أو لاغية، وأنا لست متأكدا) أن حذف الكائن أشار من قبل (أو بالأحرى إنقاص عدد مرجعها ، لكائنات COM).


وكما لاحظ شخص آخر، يجب عليك استخدام إما:

delete items[5];
items[5] = newContent;

وأو:

delete items[5];
items[5] = NULL;

وبعد delete[5]، واستخدام الوحيد الممكن للمؤشر المخزنة في items[5] يسبب لك المتاعب. ما هو أسوأ من ذلك هو أنه قد يحدث للعمل في البداية، وبدء الفشل فقط عند تخصيص شيء آخر على المساحة المستخدمة من قبل *items[5]. تلك هي الأسباب التي تجعل C / C ++ البرمجة "مثيرة للاهتمام"، أي مزعج حقا (حتى لمن يحب C مثلي).

والكتابة فقط delete items[5]; ينقذ ما يمكن أن يكون الكتابة لا طائل منه، ولكن هذا التحسين سابق لأوانه.

فقط لأكون واضحا:تشير إلى الاتصال "delete[]".أعتقد أنك تقصد delete.

أذكر هذا لأن C++ لديه عاملين منفصلين، operator delete و operator delete[].يتم استخدام الأخير لحذف صفائف الكائنات المخصصة لها operator new[], ، و اعمل لا تنطبق في هذه الحالة.لديك مجموعة من مؤشرات ل الكائنات التي يجب أن تكون قد قمت بتهيئتها باستدعاءات متكررة إليها operator new بدلا من مكالمة واحدة ل operator new[].

كل ما أحاول قوله حقًا هو:استخدامك ل delete[] محير وغامض.تغييره إلى delete.

هناك بعض الأسئلة ذات الصلة هنا:

  1. وفقًا للكود الذي نشرته، لن يتم تخصيص المصفوفة نفسها في الكومة إلا إذا تم struct هو، لذلك لا تحتاج إلى ذلك delete[] المصفوفة.إذا قمت بإنشاء المصفوفة باستخدام new[] سيكون لديك ل delete[] هو - هي.
  2. لا يوضح الكود المنشور كيفية تخصيص الكائنات التي يتم الإشارة إليها من المصفوفة.إذا قمت بتخصيص تلك الكائنات على المكدس لك لا يجب احذفها (ومرة أخرى، هذا أمر مستبعد جدًا لأن مؤشراتك ستصبح غير صالحة عندما تخرج الكائنات التي تشير إليها عن النطاق).إذا قمت بتخصيصها على الكومة (مع الجديد)، فأنت يجب حذفها عندما تقع خارج النطاق.
  3. كما اقترح آخرون بالفعل، تكون الحياة أسهل بكثير إذا كنت تستخدم حاوية - خاصة حاوية STL - ومؤشرات ذكية - وهو ما يعني الآن أن المؤشرات خارج Boost.

وC ++ ليست بلدي دعوى قوية، ولكن أنا متأكد من تريد ان تكون تسرب الذاكرة إذا قمت بتعيين المؤشر إلى NULL.

وتحرير: الذاكرة يجري تسريبه سيكون الذاكرة التي أشار إليها المؤشر في مجموعة

وتحديد العناصر [5] إلى NULL لا يحذف الذاكرة المرتبطة البند، فإنه ببساطة يضع المؤشر إلى هذا البند إلى NULL، وبالتالي يتم تسريب الذاكرة.

ويمكنك حذف هذا البند من خلال الدعوة:

delete items[5];

ومنذ C ++ لم جمع القمامة التلقائي، تحتاج إلى حذف أي الذاكرة التي لم تعد تحتاج إليها.

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