tiny_stl: :allocator之alloc

本文探讨了STL中allocator的内存管理,包括如何通过alloc类进行内存配置和释放。针对内存碎片问题,文章介绍了双层配置器策略,即使用malloc分配大块内存,以及通过free_list和内存池管理小块内存,减少外部碎片。free_list由16个链表组成,每个链表管理特定大小的内存块。当内存池不足以分配时,会尝试整合现有空间或重新申请。allocator在STL中的重要性不言而喻,其内存管理方式值得深入学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在STL中,对空间适配器allocator的操作分为两个部分,其中一个部分是alloc类提供的接口,分别负责内存配置(alloc: :allocate)和内存释放(alloc: :deallocate)。

设计需求:

  • 向堆申请空间
  • 需要考虑多线程状态(该问题比较复杂,这里不考虑)
  • 需要考虑内存不足时的措施
  • 需要考虑小型区块造成的内存碎片问题

向堆申请空间可以简单的使用malloc函数来完成,所以我们主要需要解决的问题就是最后两个,需要用到一定内存管理的知识。

内存碎片问题:
由于内存分配时要根据不同的标准进行对齐,所以通常会造成内存碎片的问题,为了解决这个问题,STL提供的配置器有两种配置方式,或者说是双层配置器。当需要分配的内存足够大时,内存分配造成的内存碎片影响较小,可以直接用malloc函数来分配,这是第一层适配器;当进行小型区块分配时,一旦分配次数较多,造成的内存碎片就会比较严重,我们需要通过某种内存管理手段来缓解这个问题。

解决方法:维护free_list(自由链表)来分配合适的内存块;内存块由内存池来分配
————————————————————————————————————————————

free_lists
free_lists包括16个free_list,换句话说就是一个包含16个链表的的链表数组,每个链表管理的内存大小均为8的倍数,这是因为内存分配默认8字节对齐,free_list的结点定义如下:

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

显然这是一个链表结构,不过为了节省空间,用了union来进行声明,不然使用了额外的指针又由占用了内存。这个结构的第二个字段看起来比较奇怪,它本质上代表了一个地址,这个地址就是该结点本身的地址,这样的定义并不代表这个结点实质的大小,举个例子:

obj *pobj = (obj*)malloc(64);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值