سؤال

لدي كتلة رمز يبدو أنها الكود وراء malloc. لكن مع مرور الكود ، أشعر أن أجزاء الكود مفقودة. هل يعرف أي شخص ما إذا كان هناك جزء من الوظيفة المفقودة؟ يفعل malloc الجمع دائمًا بين القطع المجاورة معًا؟

int heap[10000];
void* malloc(int size) {
int sz = (size + 3) / 4;
int chunk = 0;
if(heap[chunk] > sz) {
    int my_size = heap[chunk];
    if (my_size < 0) {
      my_size = -my_size
    }
    chunk = chunk + my_size + 2;
    if (chunk == heap_size) { 
      return 0;
    }
}
هل كانت مفيدة؟

المحلول

الكود وراء Malloc هو بالتأكيد أكثر تعقيدًا من ذلك. هناك العديد من الاستراتيجيات. رمز شعبي واحد هو dlmalloc مكتبة. تم وصف واحد أبسط في K&R.

نصائح أخرى

من الواضح أن الرمز غير مكتمل (لا تُرجع جميع المسارات قيمة). ولكن على أي حال ، هذا ليس ملوك "حقيقي". ربما تكون هذه محاولة لتنفيذ "نموذج" مبسط للغاية لـ "Malloc". لا يمكن أن يؤدي النهج الذي اختاره مؤلف الكود إلى تنفيذ عملي مفيد.

(و BTW ، معلمة Malloc القياسية لها نوع "size_t" ، وليس "int").

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

أظن أن أفضل نهج لهذا الرمز هو [حذف].

عندما يكون ذلك ممكنًا ، أتوقع أن يحاول Malloc تقديم طلبات مختلفة بالقرب من بعضها البعض ، حيث سيكون لها كتلة من التعليمات البرمجية المتاحة لـ Malloc ، حتى يتعين عليها الحصول على كتلة جديدة.

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

كما ذكر آخرون ، هناك مشاكل في مقتطف الكود.

يمكنك العثور على العديد من المشاريع المفتوحة المصدر لها وظيفة Malloc الخاصة بها ، وقد يكون من الأفضل أن ننظر إلى أحد هذه المشاريع ، من أجل الحصول على فكرة عما هو مفقود.

malloc هو ل مخصصة ديناميكيا ذاكرة. وهذا ينطوي sbrk, mmap, ، أو ربما بعض وظائف النظام الأخرى لنظام التشغيل Windows و/أو بنيات أخرى. لست متأكدًا مما int heap[10000] هو ، لأن الرمز غير مكتمل للغاية.

إصدار Effo أكثر منطقية قليلاً ، ولكن بعد ذلك يقدم وظيفة صندوق أسود آخر get_block, ، لذلك لا يساعد كثيرا.

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

انظر فهمي ، على نظام 32 بت ، حجم (PTR) = 4 بايت:

extern block_t *block_head; // the real heap, and its address 
                            // is >= 0x80000000, see below "my_size < 0"
extern void *get_block(int index); // get a block from the heap 
                                   // (lead by block_head)
int heap[10000]; // just the indicators, not the real heap

void* malloc(int size) 
{
    int sz = (size + 3) / 4; // make the size aligns with 4 bytes,
                             // you know, allocated size would be aligned.
    int chunk = 0; // the first check point
    if(heap[chunk] > sz) { // the value is either a valid free-block size 
                           // which meets my requirement, or an 
                           // address of an allocated block
        int my_size = heap[chunk]; // verify size or address
        if (my_size < 0) { // it is an address, say a 32-bit value which 
                           // is >0x8000...., not a size. 
              my_size = -my_size // the algo, convert it
        }
        chunk = chunk + my_size + 2; // the algo too, get available 
                                     // block index
        if (chunk == heap_size) { // no free chunks left
           return NULL; // Out of Memory
        }
        void *block = get_block(chunk);
        heap[chunk] = (int)block;
        return block;
    }
    // my blocks is too small initially, none of the blocks 
    // will meet the requirement
    return NULL;
}

تحرير: هل يمكن لشخص ما أن يساعد في شرح algo ، أي تحويل العنوان -> my_size -> قطعة؟ كما تعلمون ، عند استعادة الاتصال ، قل مجانًا (void *addr) ، وسوف يستخدم هذا العنوان -> my_size -> chunk algo أيضًا ، لتحديث الكومة [قطعة] بعد إرجاع الكتلة إلى الكومة.

إلى صغير لتكون تطبيق Malloc بالكامل

خذ llok في مصادر مكتبة C في Visual Studio 6.0 ، ستجد تنفيذ Malloc إذا كنت أتذكرها بشكل صحيح

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