c的自定义malloc函数

时间:2018-11-15 21:16:30

标签: c malloc free

我尝试在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();}

}

1 个答案:

答案 0 :(得分:3)

您的代码问题包括但不一定限于:

  • list_remove()实际上不会从列表中删除指定的块,除非它恰好是当前列表的头。因此,在其他所有情况下,halde_malloc()在修改节点的list_remove()指针时调用next后都会破坏列表。

  • list_split_AND_Remove()执行不正确的指针算术。具体来说,mblock *new = (void*)((mblock*)lastBlock+size+sizeof(mblock));并没有像您想做的那样做,因为指针算术以指向类型的大小为单位进行操作,而size参数和{{1}的结果}运算符的单位为单个字节。 (此外,这两种类型的转换都是无用的,尽管它们本身对人体无害。)

  • 您的分配器返回一个指向块头的指针,而不是指向其数据的指针。结果,用户很可能会覆盖块头的内容,从而在您以后尝试释放该块时造成严重破坏。

  • 您似乎假设sizeof对象的对齐要求为1。这可能不正确。