C++ STL空间配置源码分析以及实现一

本文主要内容如下:
1. STL为什么需要空间配置器
2. STL空间配置器实现的原理
3. STL空间配置器简单的测试

前言

很久以前看过侯捷先生的STL源码分析一书,也大致明白了STL实现的原理,但是对于编程而言,如果自己不去实现代码,调试代码,光看书,其实很难深刻的理解STL源码的逻辑(光是看书顶多也就是了解的水平,当然这是对于一般的程序员而言)。前段时间决定实现一下STL相关的容器(用到了C++11新特性),从而更加深入的理解STL,并提升自己的C++ 模板编程的功底。

先给出一张测试空间配置的运行截图(CLion + cmake):

这里写图片描述

首先本文给出的是类alloc的实现

class alloc{
   
//............
}

下篇blog给出allocator的实现(allocator主要是把上面的alloc作为静态的成员,做了一些简单的封装),并给出使用配置器allocator完成一个基本的vector(SimpleVec).

template<class T>
class allocator{
   
//..................
}

template <class T, class Alloc = allocator<T>>
class SimpleVec{
   
//.....
}

1. STL为什么需要空间配置器

程序中我们经常动态申请,释放内存,这会带来如下两个问题:

  • 问题1:就出现了内存碎片问题。(包括外碎片问题)

  • 问题2:一直在因为小块内存而进行内存申请,调用malloc,系统调用产生性能问题。

内碎片:因为内存对齐/访问效率(CPU取址次数)而产生 如 用户需要3字节,实际得到4或者8字节的问题,其中的碎片是浪费掉的。

外碎片:系统中内存总量足够,但是不连续,所以无法分配给用户使用而产生的浪费。下边简单图解

这里写图片描述


2. STL空间配置器实现的原理

这两个问题解释清楚之后,就来谈STL空间配置器的实现细节了实现策略

  if 用户申请空间 > 128:
      调用一级空间配置器
  else:
       调用二级空间配置器

大致实现为:

二级空间配置器由内存池以及伙伴系统:自由链表组成
一级空间配置器直接封装malloc,free进行处理,增加了C++中的set_handler机制(这里其实也就是个略显牵强的装饰/适配模式了),增加内存分配时客户端可选处理机制。

二级空间配置器:

这里写图片描述

成员以及接口定义如下:

class alloc{
private:
   enum EAlign{ ALIGN = 8};//小型区块的上调边界
   enum EMaxBytes{ MAXBYTES = 128};//小型区块的上限,超过的区块由malloc分配
//free-lists的个数
   enum ENFreeLists{ NFREELISTS = (EMaxBytes::MAXBYTES / EAlign::ALIGN)}; 
enum ENObjs{ NOBJS = 20};//每次增加的节点数
private:
   //free-lists的节点构造
   union obj{
      union obj *next;
      char client[1];
   };

   static obj *free_list[ENFreeLists::NFREELISTS];
private:
   static char *start_free;//内存池起始位置
   static char *end_free;//内存池结束位置
   static size_t heap_size;//
private:
   //将bytes上调至8的倍数,例如 (1, 3, 7) -> 8, (9, 13) -> 16
   static size_t ROUND_UP(size_t bytes){
      return ((bytes + EAlign::ALIGN - 1) & ~(EAlign::ALIGN - 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值