سؤال

لدي برنامج ج بسيط يحتوي على مؤشر إلى صفيف حرف. لبدء ذلك، أنا استخدم malloc, ، قم بتغيير حجمه ثم قم بتعيينه x عدد مرات في وقت لاحق في البرنامج.

عندما أزال حجمها مرة واحدة مع realloc, GDB لا تظهر أي أخطاء، ومع ذلك، إذا حاولت استدعاء وظيفة تغيير الحجم مرة أخرى، GDB يظهر الخطأ التالي:

warning: Invalid Address specified to RtlReAllocateHeap( 003E0000, 00404076 )

أي أفكار لماذا تغيير حجمها أكثر من مرة يعطي هذا الخطأ؟

تعديل

لقد لعبت حولها، ويبدو أن الخطأ لا يحدث عند التعليق على إعداد بيانات المؤشر، وهو بعد تغيير حجمه.

void setName(struct class_x *class, char *name)
{
    class->name = (char *) reallocateMemory(class->name, sizeof(char) * strlen(name) + 1);
    class->name = name;
}

void *reallocateMemory(void *member, size_t size)
{
    void *tmp = realloc(member, size);
    if(tmp == NULL)
    {
        //handle
    }
    return tmp;
}
هل كانت مفيدة؟

المحلول

class->name = name لا تفعل ما تعتقد أنه هو. يستخدم strncpy() لنسخ سلسلة الإدخال في ذاكرتك المخصصة حديثا. هذه المهمة التي لديك تسريب ذاكرتك المخصصة والكتابة فوق المؤشر. ثم في المرة القادمة التي تتصل بها setName(), ، ينتهي الأمر بالدعوة realloc() مع مؤشر لم تحصل عليه malloc(). وبعد أتوقع في مكان ما تتصل به setName() مع سلسلة ثابتة أو متغيرة عالمية، أو سلسلة متغيرة المحلية، وهذا ما يولد في نهاية المطاف الخطأ. إذا كنت تستدعي فقط setName() مع سلاسل التي حصلت على ذاكرة malloc(), ، لن ترى التحذير من GDB (ولكن لا يزال لديك الخلل!).

نصائح أخرى

قم بتشغيله تحت Valgrind أو سياج كهربائي - ستطرح هذه الذاكرة تجاوزها لك

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