STL札记1(空间配置,迭代器与traits编程)

一、空间配置器(allocator)

空间配置器是是一个默默付出的“员工”,支撑着STL的各种组件(更确切点是容器container),工欲善其事,必先利其器。下面将随笔写一写空间配置器的工作原理。

STL的配置器不仅负责分配,还负责回收。当然比较前卫,不返回给OS,而是留着自己以后用!STL配置器的特性如下:

1.具有两级配置能力

在STL设计中,以128bytes为内存申请的分水岭,大于128bytes,被视为“足够大“,而小于128bytes,被视为”过小“。根据需求大小,进行不同级别的配置。示意图如图1所示。

 

STL札记1(空间配置,迭代器与traits编程)

图1 :STL两级配置示意图

2.次级配置器构造

次级配置器的核心在于维护了一个自由链表free-lists,将128bytes拆分成16块,这有点像操作系统存储管理中的快速适配(quick fit),每一块为8bytes的整数倍(8,16,24,……,128),鉴于这个原因,配置器会将内存申请不足8的倍数时主动上调至8的倍数,(这也方便链表的管理),链表的内部数据结构被设计成共用体形式,这样就不会造成额外的浪费(指针域数据复用)

union obj{

   union obj *free_list_link;//指针,指向下一个节点

   char client_data[1];//客户端数据

   /*void *data*/   /*我倾向于这样写*/

};

有了基本的数据结构,让我们看一看free-lists的结构怎样以及怎么工作的!

  • free-lists结构

 

STL札记1(空间配置,迭代器与traits编程)

好像也就那么回事,不过这背后有很大的灵活性(flexibility)

自由链表的操作我概括了一下,主要有以下几个要点:

  1. 与散列表(以链接法解决碰撞的形式)有几分神似。

  2. 以申请内存大小求出对应的索引号,如果对应链表指针有可返回的区块,则返回,否则进行内存申请配置(一般会分配两倍大小的请求量),返回第一个区块,下次再有同样索引号的请求,就在以前分配的区块中直接返回直到内存不够。极端情况是转向第一级配置器求助(第一级配置器多了一个内存不足的异常处理)。

  3. 对链表维护的内存区块进行回收时只要修改链表指针,重新指向。

仔细思考一下,将每一块维护的内存区块都上调至8的倍数,是不是没用的内存片段就浪费喽。当然不可能每一块区块都恰好是用户所需要的。能不能改进一下呢?如果这样的设计方式用于操作系统中进程的内存分配会怎样?当然现在已经有了内存映射机制。。。。。。等等这些,都是在平时需要考究的。

 

Thinking……

 

3.STL配置器性能

当然,STL都有这么长的历史了,其性能还是禁得住考验的,对底层做了很多优化,也比较灵活。

 

二、迭代器与traits编程

利用STL进行开发,你肯定会用到迭代器(iterator),因为这是与STL打交道的唯一“开放给用户的工具“,STL关键所在。(当然也就隐藏了细节,这也是C++的脾气)。

traits的好处在于它可以隐藏所设计的迭代器的类型,当然只有它traits知道相应的型别。这不是一种智能编程,而是用户依据某些规定编写的。

 

好了,写的很简单。只是给了一个轮廓……

 

你可能感兴趣的:(C++,STL)