ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

STL源码剖析(1)空间分配器

2022-07-26 20:07:11  阅读:153  来源: 互联网

标签:分配器 STL 链表 源码 内存 freeList first 字节


配置器的接口

  • allocate:分配内存

  • deallocate:释放内存

  • construct:在已申请的内存上构造对象

  • destroy:析构对象

  • address:取某个对象的地址

  • const_address:常版本地址

  • max_size:返回可申请的最大空间

标准库的分配器

std::allocator,这个分配器类只是对原始的new和delete做了一层包装,效率很低不建议使用。

std::alloc:这个才是真正投入使用的

构造和析构

构造很容易,直接用placement new就行了

template<class T1, class T2>
inline void construct(T1 *p, const T2& value) {
    new (p) T1(value); // placement new,在以分配的内存上构造
}

析构就比较麻烦了,有好几个版本,这里看最简单的,直接调用析构函数析构

template<class T>
inline void deconstruct(T *pointer) {
    pointer->~T(); //调用析构
}

内存的申请与释放

这一块涉及到操作系统的一些知识。为了简单,我们不考虑多线程的各种同步问题。

最简单的内存分配,就是用使用new和delete,底层是c的malloc和free。但是,如果每次申请的内存都是很小一块,会导致内存碎片的问题。

STL设置了两级的分配器。如果分配的内存很大,那么就直接使用一级分配器。如果很小,就使用内存池,让二级分配器来分配内存。

一级分配器

一级分配器非常简单,主要功能如下

  • 用malloc分配内存
  • realloc重新调整大小
  • free释放内存
  • 提供函数指针,供用处处理内存不足的情况

二级分配器

二级分配器用来分配小于128k的内存,大于这个数的内存交给一级分配器完成。

二级分配器用内存池来维护一系列内存块。首先,分配器保存了一个freeList,这个freeList是一个链表数组,保存了8的倍数的内存块,并以链表维护。

解释一下,freeList的定义是这样的:void *freeList[16],其中freeList[0]保存一个链表,这个链表每个节点的大小都是8个字节,同理,freeList[1]保存一个节点为16字节大小的链表。那这样第16个就是保存128字节大小的内存块。

有个问题是链表的next指针,如果单独在每个节点中加个next,开销还是很大的。这里我们可以用union,当内存节点在freeList中的时候,就当作一个next指针。当该内存节点被申请后,就当作真实数据。

还有一个需要注意的是,我们会对申请的字节做一个8字节对齐(便于内存的分配)。比如我们申请2个字节,会自动对齐到8字节;申请15字节会对齐到16字节。

处理内存的工具

这是几个全局函数,在大规模内存上构造对象。

uninitialized_copy

// 将first和last之间的对象产生一个拷贝,并用于构造result到result+(last-frist)之间的内存。
uninitialized_copy(first, last, result);

uninitialized_fill

// 用T构造first到last之间的内存
uninitialized_fill(first, last, T);

uninitialized_fill_n

// 用T构造first到first + n之间的内存
uninitialized_fill_n(first, n, T);

标签:分配器,STL,链表,源码,内存,freeList,first,字节
来源: https://www.cnblogs.com/destinyzk/p/16522447.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有