【C】动态内存管理

 malloc

首先定义一个block链表的头指针,初始化为NULL,另外,我们需要剩余空间至少有 BLOCK_SIZE  + 4 才执行分离操作

 

#define align4(x) (((((x)-1)>>2)<<2)+4)
#define BLOCK_SIZE 12

void *base = NULL;

void *malloc(size_t size)
{   
    t_block b, last;
    size_t s;

    s = align4(size);
    if(base)
    {
        //first find a block
        last = base;
        b = find_block(&last, s);
        if(b)
        {
            //can we split
            if((b->size - s) >= (BLOCK_SIZE + 8))
                split_block(b, s);
            b->free = 0;
        }
        else
        {
            //no fitting block, extend the heap
            b = extend_heap(last, s);
            if(!b)
                return NULL;
        }
    }
    else
    {
        //first time
        b = extend_heap(NULL, s);
        if(!b)
            return NULL;
        base = b;
    }
    return b->data;
}

calloc

 自动将分配到的内存空间初始化

void *calloc(size_t numitems, size_t size)
{
    size_t *new;
    size_t s, i;
    new = malloc(numitems * size);
    if(new)
    {
//因为申请的内存总是4的倍数,所以这里我们以4字节为单位初始化
        s = align4(numitems * size) >> 2;
        for(i = 0; i < s; ++i)
            new[i] = 0;
    }
    return new;
}

free

先合并相邻的空闲内存块,合并之后,再检查是否还有空闲的相邻内存块,如果有则继续合并,直到最后,该内存块是最大的连续内存块。

void free(void *p)
{
    t_block b;
    if(valid_addr(p))//地址的有效性验证
    {
        b = get_block(p);//得到对应的block
        b->free = 1;

//如果相邻的上一块内存是空闲的就合并,
//合并之后的上一块还是空闲的就继续合并,直到不能合并为止
        while(b->prev && b->prev->free)
        {
            b = fusion(b->prev);
        }

//同理去合并后面的空闲block
        while(b->next)
            fusion(b);//内部会判断是否空闲

//如果当前block是最后面的那个block,此时可以调整break指针了
        if(NULL == b->next)
        {
            if(b->prev)//当前block前面还有占用的block
                b->prev->next = NULL;
            else//当前block就是整个heap仅存的
                base = NULL;//则重置base
            brk(b);//调整break指针到b地址位置
        }
        //否则不能调整break
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值