动态内存分配

内存分配是在预先设定的未使用内存堆中分配出需求的空间,然后将该空间起始地址返回给调用者,操作系统内核有一套自己的数据结构描述、记录哪些空间范围已经被分配、哪些未使用,不同操作系统有不同的内存分配策略。


一种内存堆分配方法(摘自《嵌入式网络那些事》):

void *mem_malloc(mem_size_t size)
{
    mem_size_t ptr, ptr2;        //局部变量,保存内存块起始地址偏移量
    struct mem *mem, *mem2;
    if(size == 0){
        return NULL;
    }
    size = LWIP_MEM_ALIGN_SIZE(size);   //将size修正为内存对齐字节数的整数倍
    if(size < MIN_SIZE_ALIGNED){
        size = MIN_SIZE_ALIGNED;
    }
    if(size > MEN_SIZE_ALIGNED){
        return NULL;
    }
    
    //从lfree开始遍历,找出第一个长度大于size的空闲内存块
    for(ptr = (u8_t*)lfree-ram; ptr < MEM_SIZE_ALIGNED-size;
                                                ptr = ((struct mem*)&ram[ptr])->next)
    {
        mem = (struct mem*)&ram[ptr];  
        //若该内存块未使用,且其空间不小于(用户请求大小+系统结构体mem)
        if((!mem->used)&&(mem->next-(ptr+SIZEOF_STRUCT_MEM)) >= size){
            //接下来判断是将该内存块全部分配给用户,还是截取其中的一部分,判断标准是:
            //若做截取,判断剩下的部分是否能组成一个最小的内存块,即是否能剩下
            //SIZEOF_STRUCT_MEM+MIN_SIZE_ALIGNED的大小
            if(mem->next-(ptr+SIZEOF_STRUCT_MEM) >= 
                                (size+SIZEOF_STRUCT_MEM+MIN_SIZE_ALIGNED)){
                //需截取
                ptr2 = ptr+SIZEOF_STRUCT_MEM+size;  //分配后剩余空间起始处偏移量
                mem2 = (struct mem*)&ram[ptr2];
                mem2->used = 0;
                mem2->next = mem->next;  //将空闲块插入到原空闲内存块链表中
                mem2->prev = ptr;
                mem->next = ptr2;
                mem->used = 1;
                if(mem2->next != MEM_SIZE_ALIGNED){
                    ((struct mem*)&ram[mem2->next])->prev = ptr2;
                }
                MEM_STATS_INC_USED(used, (size+SIZEOF_STRUCT_MEM));//增加全变量
            }else {//直接分配,不用截取
                mem->used = 1;
                MEM_STATS_INC_USED(used, mem->next-((u8_t*)mem-ram));//增加全变量
            }
            //分配完毕
            if(mem == lfree){ //lfree指向的内存块被分配出去时,更新lfree
                while(lfree->used&&lfree != ram_end){
                    lfree = (struct mem*)&ram[lfree->next];
                }
            }
            return (u8_t*)mem + SIZEOF_STRUCT_MEM; //分配成功,返回可用内存块起始区域
        }//此内存块不满足要求,下一个for循环
    }//所有内存块都不满足要求
    
    return NULL;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值