Собственный свободный () в c |блоки данных без расплава - PullRequest
0 голосов
/ 21 ноября 2018

Я должен был написать свою собственную функцию free & malloc.До сих пор у меня не было проблем с этим, но теперь я должен объединить соседние блоки свободной памяти в функции halde_free ().Я был бы очень признателен, если бы вы могли помочь мне в этом.

    #include "halde.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>

/// Magic value for occupied memory chunks.
#define MAGIC ((void*)0xbaadf00d)

/// Size of the heap (in bytes).
#define SIZE (1024*1024*1)

/// Memory-chunk structure.
struct mblock {
    struct mblock *next;
    size_t size;
    char memory[];
};

/// Heap-memory area.
char memory[SIZE];

/// Pointer to the first element of the free-memory list.
static struct mblock *head;

/// Helper function to visualise the current state of the free-memory list.
void halde_print(void) {
    struct mblock* lauf = head;

    // Empty list
    if ( head == NULL ) {
        fprintf(stderr, "(empty)\n");
        return;
    }

    // Print each element in the list
    while ( lauf ) {
        fprintf(stderr, "(addr: 0x%08zx, off: %7zu, ", (uintptr_t) lauf, (uintptr_t)lauf - (uintptr_t)memory);
        fflush(stderr);
        fprintf(stderr, "size: %7zu)", lauf->size);
        fflush(stderr);

        if ( lauf->next != NULL ) {
            fprintf(stderr, "  -->  ");
            fflush(stderr);
        }
        lauf = lauf->next;
    }
    fprintf(stderr, "\n");
    fflush(stderr);
}

void *halde_malloc (size_t size) {
    static int initialized = 0;

    if(initialized == 0){
        head = (struct mblock *) memory;
        head->size = sizeof(memory) - sizeof (struct mblock);
        head->next = NULL;
        initialized = 1;
    }

    if(size == 0){
        return NULL;
    }

    struct mblock *lauf = head;
    struct mblock **prev_next = &head;

    while (lauf != NULL && lauf->size < size){
        prev_next = &(lauf->next);
        lauf = *prev_next;
    }

    if(lauf == NULL){
        errno = ENOMEM;
        return NULL;
    }

    if((lauf->size -size) <= sizeof(struct mblock)){
        *prev_next = lauf->next;
    } else {
        //mblock anlegen und init.
        struct mblock* neu = (struct mblock*) (lauf->memory + size);
        neu->size = lauf->size - sizeof(struct mblock) - size;
        neu->next = lauf->next;

        //mblock anpassen
        lauf->size = size;

        //verketten wiederherstellen
        *prev_next = neu;
    }

    lauf->next = MAGIC;

    return lauf->memory;
}

void halde_free (void *ptr) {
    if(ptr == NULL){
        return;
    }

    struct mblock *mbp = (struct mblock *) ptr - 1;
    if(mbp->next != MAGIC){
        abort();
    } else {
        mbp->next = head;
        head = mbp;
    }
}

Код работает до сих пор, но я действительно не знаю, как объединять блоки. Управление памятью выполняется через просто связанные списки.Переменная head указывает на первый свободный блок памяти.

Моя идея состоит в том, чтобы объединить блоки непосредственно в остальной части, но у меня нет хорошей идеи сделать это ..

...