لقد اكتشفت كيفية كتابة realloc، لكني أعلم أن الكود غير صحيح؟

StackOverflow https://stackoverflow.com/questions/1641067

  •  08-07-2019
  •  | 
  •  

سؤال

ما قررت القيام به هو

  • اتصل بمالوك
  • انسخ الكتلة القديمة إلى الكتلة الجديدة
  • تحرير الكتلة القديمة
  • وأعد المؤشر إلى الكتلة الجديدة

الكود أدناه هو ما لدي حتى الآن...ولكني أعلم أنه ليس صحيحًا...أي مساعدة في إصلاح الكود سيكون موضع تقدير كبير...

إذا كنت بحاجة إلى رمز أكثر مما قدمته، فلدي منشور سابق لهذا والذي يوضح كل الكود.أنا جديد لذا لا يوجد سوى هذه المشاركة وآخر مشاركة قمت بها.شكرًا لك.

void *mm_realloc(void *ptr, size_t size)
{
int i, p = *ptr;

 // make a call to malloc to find space
 //allocate memory

 ptr = malloc(size_t*sizeof(int));

 //copying old block to new block
 if(ptr!=NULL)
     for(i=0 ; i<size_t ; i++) 
     {
     *(ptr+i) = i;
     }

//freeing old block
free(ptr);

//return pointer to new block
return *ptr;
}
هل كانت مفيدة؟

المحلول

ومن الناحية المثالية، أ realloc() سوف نرى ببساطة ما إذا كانت هناك ذاكرة خالية كافية خارج الكتلة الحالية، وإذا كان الأمر كذلك، فما عليك سوى ضبط هياكل بيانات الساحة لتوسيع الكتلة الحالية في مكانها.يؤدي هذا إلى التخلص من عملية النسخ الباهظة الثمن ويقلل من فرص فشل التخصيص.وذلك لزيادة الحجم.للتقليل، يجب أن تكون قادرًا على القيام بذلك في مكانه دائمًا، وإرسال ما تبقى من الكتلة الحالية مرة أخرى إلى المجموعة المجانية.

من خلال إجراء مالوك/مجاني، إذا كان لديك 100 ألف في الساحة مع كتلة واحدة مخصصة تبلغ 60 ألفًا، فاتصل برقمك mm_realloc لضبط الحجم إلى 50 كيلو سوف تفشل.

ومع ذلك، فهو أ عملي الحل، على الأقل للمحاولة الأولى، فإليك كيفية تنفيذه:

void *mm_realloc (void *ptr, size_t size) {
    int minsize;
    void *newptr;

    // Allocate new block, returning NULL if not possible.

    newptr = malloc (size);
    if (newptr == NULL) return NULL;

    // Don't copy/free original block if it was NULL.

    if (ptr != NULL) {
        // Get size to copy - mm_getsize must give you the size of the current block.
        // But, if new size is smaller, only copy that much. Many implementations
        // actually reserve the 16 bytes in front of the memory to store this info, e.g.,
        // +--------+--------------------------------+
        // | Header | Your data                      |
        // +--------+--------------------------------+
        //           ^
        //           +--- this is your pointer.
        // <- This is the memory actually allocated ->

        minsize = mm_getsize (ptr);
        if (size < minsize)
           minsize = size;

        // Copy the memory, free the old block and return the new block.

        memcpy (newptr, ptr, minsize);
        free (ptr)
    }

    return newptr;
}

هناك شيء واحد ستلاحظه مفقودًا من جهازك وهو أنه يجب عليه نسخ ما يكفي فقط من البايتات لملف الأصغر من الكتل القديمة والجديدة.وإلا فإنك تخاطر بمقالب جوهرية عن طريق تجاوز أحدها.

بالإضافة إلى ذلك، لم تقم حلقتك بنسخ البيانات فعليًا، بل قامت بتعيين كل بايت من الكتلة على إزاحتها، وفقدت المؤشر القديم عند تخصيص المؤشر الجديد، ومن هنا استخدمي newptr لإبقائهم منفصلين.

نصائح أخرى

عليك أن تعرف حجم الكتلة القديمة وكذلك الحجم الجديد.يجب عليك نسخ الحجم الأصغر من الحجمين فوق الكتلة الجديدة.

عليك أيضًا التأكد من عدم تدمير (تحرير) الكتلة القديمة في حالة فشل malloc() - ما عليك سوى إرجاع 0.

لا تحتاج أيضًا إلى ضرب الحجم بـ "sizeof(int)" في malloc();أنت تقوم بالفعل بالتخصيص الشامل بعامل 4 أو أكثر (من الناحية النظرية، قد يكون العامل 2 فقط، لكن القليل من الأشخاص يستخدمون مترجمات 16 بت هذه الأيام).

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

لماذا تكتب إجراءات التخصيص الخاصة بك على أي حال؟

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