欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-09 15:21:55
...

传送:基于Keil C 编写的更加简洁的版本(空间复杂度比较低)

---------------------------------------------------------------------------------------------

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+2000)))
    {
        struct block* curr=ptr;
        --curr;
        curr->free=1;
        merge();
     }
    else
        return;
}