سؤال

أعلم أن هذا عام حقًا ، لكنني أحصل على "هذا" (انظر أدناه) عندما أقوم بتشغيل ملف .c في Visual C ++ 2008 Express. يحدث ذلك عندما أتصل malloc (). خذ عملي على هذا - أقوم بتخصيص الذاكرة بشكل صحيح.

كومة [code.exe]: الكومة: حرة كتلة الكومة 211A10 المعدلة في 211AF8 بعد تحريرها ، أثارت النوافذ نقطة توقف في code.exe.

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

قد يكون هذا أيضًا بسبب الضغط على المستخدم F12 بينما يتم التركيز على code.exe.

قد تحتوي نافذة الإخراج على المزيد من المعلومات التشخيصية.

لماذا أحصل على هذا الخطأ؟ ماذا يعني هذا حتى؟

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

المحلول

تخبرك رسالة الخطأ بالضبط لماذا حصلت عليها:

تم تعديل كتلة الكومة الحرة 211A10 في 211AF8 بعد إطلاق سراحه

كان لديك كومة مخصصة تم تحريرها ثم كتب شيء إلى هذا المجال من الذاكرة. ليس من الجيد الكتابة إلى كتلة محررة من الذاكرة.

نصائح أخرى

الخطأ ليس في الواقع يحدث عندما تتصل بمولوك ؛ هذا فقط عندما يؤدي إلى إجراء فحص مجاني للكومة. حدث الخطأ الفعلي في مكان ما من قبل. لقد قمت ببعض الذاكرة على العنوان 211A10 (هذا ما عاد إليه Malloc). ثم أنت (أو بعض lib آخر) حررته. ثم في وقت لاحق ، عندما تتصل Malloc في وضع التصحيح ، فإنه يقوم بمسح الكومة بأكملها - كجالة لك ، المبرمج الفقير. يكتشف أن شخصًا ما (أو بعض lib الذي تتصل به) كتب على جزء من تلك الصفيف ، وتحديداً في العنوان 211AF8 ، أو 0xe8 بايت في المصفوفة. لذا ، فأنت إما لا تزال تتسكع على مؤشر تم تحريره (على الأرجح) واستخدامه ، أو أنك مجرد تحريك ذاكرة عشوائية.

في حالتي ، مع أعراض مماثلة ، كانت المشكلة عدم تطابق محاذاة الهيكل (/ZP)

لقد حددت للرمز محاذاة بنية مختلفة عن المكتبات الخارجية (WXWidgets). ومع ذلك ، تم بناء WXWidgets مع Makefile ، لذلك تم تجميعها باستخدام Defaut /ZP. و wxwidget مرتبطة بشكل ثابت.

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

HEAP[Code.exe]: HEAP: Free Heap block 211a10 modified at 211af8 after it was freed 
Windows has triggered a breakpoint in Code.exe.

المحلول:

  • تأكد من استخدام نفس "محاذاة عضو الهيكل" في جميع الكود والمكتبات.

  • أفضل قاعدة هي تحديد /ZP لاستخدام القيمة "الافتراضية". في Visual Studio ، ضمن خصائص توليد رمز C/C ++

  • استشهد MSDN: "يجب ألا تستخدم هذا الخيار إلا إذا كان لديك متطلبات محاذاة محددة." انظر هنا

  • نصيحة: استخدام #Pragma Pack إذا كنت بحاجة إلى التحكم في المحاذاة في بعض الهياكلانظر هناك

مثال:

#pragma pack(1) // - 1 byte alignment 

    typedef union 
    {   
        u64 i;
        struct{             // CUSTOMS.s is used by Folders
            u32  uidx;      // Id, as registered 
            byte isoS, isoT;    // isoS/isoT combination.
            byte udd0, udd1;    // custom values (TBD)
        }s;
    }CUSTOMS;

    struct Header   // exactly 128 bits
    {       
        u32 version;        
        u32 stamp;          // creation time
        CUSTOMS customs;                // properties 
    }

#pragma pack()  // this pragma restores the **default** alignment

*

نأمل أن يساعد هذا التفسير ، لأن هذا ليس في الواقع خطأ في الكود ، ولكن خطأ تكوين خطير: من الصعب اكتشاف لأنه يقع في خيارات التحويل البرمجي الدقيقة. شكرا للجميع،

    *

أنا أقوم بتخصيص الذاكرة بشكل صحيح.

أعتقد أن المشكلة هنا هي أنك تقوم بإلغاء توضيح الذاكرة بشكل لا أساس لها. ما أعنيه بهذا هو أنك قد تحاول استخدام الذاكرة المحررة. آسف لا أستطيع المساعدة في ذلك ، ربما يمكنك إضافة الكود الفعلي.

خذ عملي على هذا - أقوم بتخصيص الذاكرة بشكل صحيح.

لكن هل أنت متأكد من أن المخازن المؤقتة كلها من الحجم الصحيح وأنت free() لهم بشكل صحيح؟ يمكن أن تؤدي الحشرات المزدوجة والفيضان المخزن المؤقت بسهولة إلى فساد الكومة الذي يمكن أن يسبب malloc() للفشل بكل أنواع الطرق.

إذا كانت هياكل الإدارة تستخدم داخليًا malloc() تتلف ، وعادة ما لا يؤدي إلى خطأ على الفور. ولكن في وقت لاحق يدعو إلى malloc() أو free() سيفشل تلك المحاولة لاستخدام هذه الهياكل التالفة في القيام بأشياء غير منتظمة.

هل تستخدم malloc () على صفيف؟ لأنني فكر في قد يكون الخطأ فقط تنسى تخصيص موقع ذاكرة إضافي في النهاية - ما يحدث هو أنه يحاول الكتابة إلى هذا الموقع ، والذي لم يتم تخصيصه له ، ويفترض أنه يحاول الكتابة إلى مكان تم إطلاق سراحه بالفعل.

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