我尝试在c中编写自己的自定义malloc和free函数。我为此工作了大约12个小时,尝试了很多事情。但这是行不通的。
也许你们可以找出错误。使用下一个指向特定地址的指针从列表中删除已分配的内存,以便稍后在free函数中对其进行标识。当前的错误是分割方法中的分段故障11。
C档案:

头:

#define MAGIC ((void*)0xbaadf00d)
#define SIZE (1024*1024*1)

typedef struct mblock {
    struct mblock *next;
    size_t size;
    char memory[];
}mblock;

char memory[SIZE];

static struct mblock *head;


malloc:

void *halde_malloc (size_t size) {
    printf("Starting\n");
    printf("%zu\n",size);
    if(size <= 0) {return NULL;}
    if(head == NULL){
        initializeBlock();
        printf("Memory initialized\n");
    }
    mblock *temp_block = head;
    while(temp_block != NULL) {
        printf("IN\n");
        if(temp_block->size == size) {
            list_remove(temp_block);
            temp_block->next = MAGIC;
            return (void*)(temp_block);
        } else if(temp_block->size > size) {
            size_t temp_size = temp_block->size;
            printf("size IS more than equal\n");
            list_split_AND_Remove(temp_size - size, temp_block);
            temp_block->size = size;
            temp_block->next = MAGIC;
            return (void*)(temp_block);
        }
        temp_block = temp_block->next;
        printf("One block checked\n");
    }
    errno = ENOMEM;
    return NULL;
}


初始化:

void initializeBlock(){
    printf("Initializing\n");
    head = (mblock*)memory;
    head->size=sizeof(memory)-sizeof(mblock);
    head->next=NULL;
}


分裂:

void list_split_AND_Remove(size_t size, mblock *lastBlock) {
    printf("Split\n");
    mblock *new = (void*)((mblock*)lastBlock+size+sizeof(mblock));
    new->size = size - sizeof(mblock);
    new->next = lastBlock->next;
    lastBlock->next = new;
    printf("START REMOVE");
    list_remove(lastBlock);

}


去掉:

void list_remove(mblock *p) {
    printf("Remove\n");
    mblock *temp_block = head;
    if(p == head) {
        if(head->next == NULL) {
            head = NULL;
            return;
        } else {
            head = p->next;
            return;
        }
    }
    while(temp_block->next != NULL) {
        if(temp_block->next == p) {
            printf("Found P:");
            temp_block = p->next;
            return;
        }
        temp_block = temp_block->next;
    }

}


自由:

void halde_free (void *ptr) {
    printf("FREE\n");
    mblock *new_block = ptr;
    if(new_block->next == MAGIC) {
        new_block->next = head;
        head = new_block;
    } else {abort();}

}

最佳答案

您的代码存在的问题包括但不限于:


list_remove()实际上不会从列表中删除指定的块,除非它恰好是当前列表的头。因此,在所有其他情况下,halde_malloc()在修改节点的list_remove()指针时调用next后都会破坏列表。
list_split_AND_Remove()执行错误的指针算术。具体来说,mblock *new = (void*)((mblock*)lastBlock+size+sizeof(mblock));并没有执行您想做的事情,因为指针算术以指向类型的大小为单位进行操作,而size参数和sizeof运算符的结果则使用单独的单位个字节。 (此外,这两种类型的转换都是无用的,尽管它们本身对人体无害。)
您的分配器返回一个指向块头的指针,而不是指向其数据的指针。结果,用户很可能会覆盖块头的内容,从而在您以后尝试释放该块时造成严重破坏。
您似乎假设mblock对象的对齐要求为1。这可能不是正确的。

10-08 06:51