浅析STL空间配置器

    STL分为6大组件,容器、算法、迭代器、适配器、仿函数、空间配置器;容器距离我们使用者最近,但是容器之下,是空间配置器。没有空间,不成容器。

    STL的空间配置器分类:

  1. 一级空间配置器---__malloc_alloc_template
  2. 二级空间配置器--__default_alloc_template

    上图是SGI STL空间配置器的结构,用户调用配置器中的allocate(size_t n)申请内存并返回空间指针,调用deallocate(void *p, size_t n)释放p指向的内存。​​​

一级配置器中的allocate(size_t n):

  1.     __malloc_alloc_template中的allocate()直接调用malloc(),如果内存不足则再调用oom_malloc(),否则直接返回
  2. oom_malloc()中不断尝试调用malloc(),并且调用用户设置的处理例程(void (*oom_handler)()),如果用户没有设置处理例程,则跑出异常且exit(0),否则返回获得的空间指针

二级配置器中的allocate(size_t n):

  1.     __default_alloc_template中的allocate()判断size是否大于128,大于则转给一配置器中的allocate()处理,否则检查free_list[16]中是否有有适当的区块,存在则从free_list[16]中抽取区块并返回区块指针,否则调用refill()填充free_list[16]并返回得到的第一个区块
  2. refill()直接调用chunk_alloc()从内存池中申请区块,默认申请20个区块,实际获得的区块以参数传回(传址),判断获得的区块是否等于1,如果等于则直接返回区块指针,无须调整free_list[16],否则返回头区块指针,并且将后面的区块链接起来(使用侵入式链表)并挂接到free_list[i]上
  3. chunk_alloc()查看内存池余下空间是否满足20个区块,满足则返回20个区块,不满足则再检查是否满足1个区块以上,满足则返回x个区块,并修改nobjs的值以传出实际返回的区块个数,否则将剩余的区块放入合适的free_list[i]中,再度调用malloc()。成功则返回,失败则检查free_list[16]中是否存在尚未使用的足够区块,存在则回收到内存池中再递归调chunk_alloc(),否则转到一级空间配置器。(PS:返回区块之后需要调整内存池中的头指针---start_free;区块插入到free_list中时用的是头插法)

    以下下是free_list[16]的示意图:

        

    STL中对于free_list使用了

union obj{
   obj *next;
   char client_data[1];
}

来链接区块,因为区块挂接在free_list上时是不存储内容的,所以可以用侵入式链表来链接。此obj直接位于区块的前四字节,存储下一个区块的地址(即next),经过调试,知道client_data此时只是下个区块地址的第一个字节,我暂且认为它在调试的时候起到一个辅助作用(没有找到太可靠的资料来说明client_data[1])。

 

 

转载于:https://my.oschina.net/u/3281747/blog/875605

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值