malloc函数详解之自己用C语言写出实现malloc()和free()功能的函数

时间:2022-11-02 20:44:17

malloc()函数使用来动态分配内存空间,free()用来释放内存空间,两者搭配使用,若忘记free,则可能引起内存泄漏。

为什么要自己编写malloc()函数:在嵌入式编程中,内存的大小都是有限的,考虑到成本问题,我们尽量包含少一点的函数库,减小不必要的浪费。

malloc函数实现的原理:

malloc函数详解之自己用C语言写出实现malloc()和free()功能的函数

C语言实现过程:

首先是定义一块区域:

char memory[2000];                             //模拟一个堆空间

定义一个区块的结构体:

struct block{  
    size_t size;                  //区块大小  
    int free;                     //是否已使用  
    struct block *next;           //指向下一个区块  
};


对模拟空间进行初始化:

void initialize()  
{  
    struct block *freeList = (void *)memory;                 
    freeList->size=2000-sizeof(struct block);              //可用空间大小  
    freeList->free=1;                                      //1:空闲 0:使用  
    freeList->next=NULL;                                   //指向空  
}


MyMalloc()函数编写:
void *MyMalloc(size_t noOfBytes)
{
    struct block *curr,*prev;
    void *result;
    if(!(freeList->size))
    {
        initialize();
    }
    curr=freeList;
    while((((curr->size)<noOfBytes)||((curr->free)==0))&&(curr->next!=NULL))
    {
        prev=curr;
        curr=curr->next;
    }
    if((curr->size)==noOfBytes)
    {
        curr->free=0;
        result=(void*)(++curr);
        return result;
    }
    else if((curr->size)>(noOfBytes+sizeof(struct block)))            //所需要的内存大小小于区块大小
    {
        split(curr,noOfBytes);                                        //分割区块函数
        result=(void*)(++curr);                                       //使用的位置
        return result;
    }
    else
    {
        result=NULL;
        return result;
    }
}

split()函数实现:

void split(struct block *fitting_slot,size_t size)
{
    struct block *new=(void*)((void*)fitting_slot+size+sizeof(struct block));   //定义new的地址
    new->size=(fitting_slot->size)-size-sizeof(struct block);                   //定义size大小
    new->free=1;                                                                //设置是否工作
    new->next=fitting_slot->next;                                               //独立出去,形成新的块
    fitting_slot->size=size;
    fitting_slot->free=0;
    fitting_slot->next=new;
}
Myfree()函数:
void merge()
{
    struct block *curr,*prev;
    curr=freeList;
    while((curr->next)!=NULL)
    {
        if((curr->free) && (curr->next->free))
        {
            curr->size += (curr->next->size)+sizeof(struct block);
            curr->next = curr->next->next;
        }
        prev=curr;
        curr=curr->next;
     }
}

void MyFree(void* ptr)
{
    if(((void*)memory<=ptr)&&(ptr<=(void*)(memory+20000)))
    {
        struct block* curr=ptr;
        --curr;
        curr->free=1;
        merge();
     }
    else
        return;
}
更加简洁的版本(空间复杂度比较低)