众所周知,一般情况下,一个程序包括数据结构和相应的算法,而数据结构作为存储数据的组织形式,与内存空间有着密切的联系. 在C++ STL中,空间配置器便是用来实现内存空间(一般是内存,也可以是硬盘等空间)分配的工具,他与容器联系紧密,每一种容器的空间分配都是通过空间分配器alloctor实现的.理解alloctor的实现原理,对内存结构以及数据存储形式会有更清晰直观的认识.

1.两种C++类对象实例化方式的异同

在c++中,创建类对象一般分为两种方式:一种是直接利用构造函数,直接构造类对象,如 Test test();另一种是通过new来实例化一个类对象,如 Test *pTest = new Test;那么,这两种方式有什么异同点呢?

我们知道,内存分配主要有三种方式:

(1)静态存储区分配:内存在程序编译的时候已经分配好,这块内存在程序的整个运行空间内都存在.如全局变量,静态变量等.
(2)栈空间分配:程序在运行期间,函数内的局部变量通过栈空间来分配存储(函数调用栈),当函数执行完毕返回时,相对应的栈空间被立即回收. 主要是局部变量.
(3)堆空间分配:程序在运行期间,通过在堆空间上为数据分配存储空间,通过malloc和new创建的对象都是从堆空间分配内存,这类空间需要程序员自己来管理,必须通过free()或者是delete()函数对堆空间进行释放,否则会造成内存溢出.

那么,从内存空间分配的角度来这两种方式的区别,就比较容易区分:

对于第一种方式来说,是直接通过调用Test类的构造函数来实例化Test类对象的,如果该实例化对象是一个局部变量,则其是在栈空间分配相应的存储空间.
对于第二种方式来说,就显得比较复杂.这里主要以new类对象来说明一下.new一个类对象,其实是执行了两步操作:首先,调用new在堆空间分配内存,然后调用类的构造函数构造对象的内容;同样,使用delete释放时,也是经历了两个步骤:首先调用类的析构函数释放类对象,然后调用delete释放堆空间.

2.C++ STL空间配置器实现

很容易想象,为了实现空间配置器,完全可以利用new和delete函数并对其进行封装实现STL的空间配置器,的确可以这样.但是,为了最大化提升效率,SGI STL版本并没有简单的这样做,而是采取了一定的措施,实现了更加高效复杂的空间分配策略.由于以上的构造都分为两部分,所以,在SGI STL中,将对象的构造切分开来,分成空间配置和对象构造两部分.

内存配置操作:alloc::allocate()实现
内存释放操作:alloc::deallocate()实现
对象构造操作: ::construct()实现
对象释放操作: ::destroy()实现

STL对象构造与释放结构图如下所示:

关于对象的构造和释放的实现,此处buxijia不细讲,但其中利用了replacement new技术,单独说一下.

replacement new技术实际上就是将一个对象构造在指定的内存区域中.该内存区域可以是静态数据区,栈空间或者是堆空间,对于内存的管理方式不变.如下代码说明replacement new的用法.

#include<new.h> Class Test {...}; char *p = (char *)malloc(sizeof(Test)); Test *tp = new(p) Test();//replacement new
关于内存空间的配置与释放,SGI STL采用了两级配置器:一级配置器主要是考虑大块内存空间,利用malloc和free实现;二级配置器主要是考虑小块内存空间而设计的(为了最大化解决内存碎片问题,进而提升效率),采用链表free_list来维护内存池(memory pool),free_list通过union结构实现,空闲的内存块互相挂接在一块,内存块一旦被使用,则被从链表中剔除,易于维护.
free_list的结构如下所示:
union obj{ union obj *free_list_link; char client_data[1]; };
free_list的实现技巧如下图所示:

从free_list取出内存块示意图:

释放内存块加入free_list示意图:

以上内容仅供参考学习,欢迎大家交流讨论.转载请注明出处.

参考资料

[1] https://www.cnblogs.com/tony-li/p/4111588.html
[2]STL源码剖析

C++ STL学习之 空间配置器(allocator)的更多相关文章

  1. C++ 空间配置器(allocator)

    C++ 空间配置器(allocator) 在STL中,Memory Allocator 处于最底层的位置,为一切的 Container 提供存储服务,是一切其他组件的基石.对于一般使用 STL 的用户 ...

  2. STL学习笔记:空间配置器allocator

    allocator必要接口: allocator::value_type allocator::pointer allocator::const_pointer allocator::referenc ...

  3. STL源码剖析——空间配置器Allocator#1 构造与析构

    以STL的运用角度而言,空间配置器是最不需要介绍的东西,因为它扮演的是幕后的角色,隐藏在一切容器的背后默默工作.但以STL的实现角度而言,最应该首先介绍的就是空间配置器,因为这是这是容器展开一切运作的 ...

  4. 《STL源码剖析》chapter2空间配置器allocator

    为什么不说allocator是内存配置器而说是空间配置器,因为空间不一定是内存,也可以是磁盘或其他辅助介质.是的,你可以写一个allocator,直接向硬盘取空间.sgi stl提供的配置器,配置的对 ...

  5. STL源码剖析 — 空间配置器(allocator)

    前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配 ...

  6. STL源码剖析——空间配置器Allocator#2 一/二级空间配置器

    上节学习了内存配置后的对象构造行为和内存释放前的对象析构行为,在这一节来学习内存的配置与释放. C++的内存配置基本操作是::operator new(),而释放基本操作是::operator del ...

  7. STL之空间配置器allocator

    摘要 C++STL的空间配置器将内存的分配.释放,对象的构造.析构都分开执行,内存分配由alloc::allocate()负责,内存的释放由alloc::deallocate()负责:对象的构造由:: ...

  8. STL源码剖析——空间配置器Allocator#3 自由链表与内存池

    上节在学习第二级配置器时了解了第二级配置器通过内存池与自由链表来处理小区块内存的申请.但只是对其概念进行点到为止的认识,并未深入探究.这节就来学习一下自由链表的填充和内存池的内存分配机制. refil ...

  9. STL——模拟实现空间配置器

    目录 问题 SGI版本空间配置器-std::alloc 一级空间配置器 二级空间配置器 Refill.chunkAlloc函数 最后,配置器封装的simple_alloc接口 问题 我们在日常编写C+ ...

随机推荐

  1. linux 乌班图 xshell链接不上服务器

    输入  ps -e |grep ssh ,如果没有任何反应则是没有安装 命令 sudo apt-get install openssh-server 然后出现是否同意-Y,同意进行自动下载 如果提示  ...

  2. 适合前端学习JS的网站

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript

  3. 调用脚本的方式自动的创建或者是更新oracle数据库自带的Seq序列号的值

    执行脚本: CREATE OR REPLACE PACKAGE PKG_QUERY IS -- Author : ADMINISTRATOR -- Created : 2016/12/8 星期四 10 ...

  4. pandas 中处理数据的函数和方法

  5. python-argparse使用

    官方文档:https://docs.python.org/zh-cn/3.7/library/argparse.html?highlight=argparse#module-argparse argp ...

  6. pta编程总结3

    7-1 抓老鼠啊~亏了还是赚了? (20 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T),或者放置一块 ...

  7. python提取网页表格并保存为csv

    0. 1.参考 W3C HTML 表格 表格标签 表格 描述 <table> 定义表格 <caption> 定义表格标题. <th> 定义表格的表头. <tr ...

  8. [C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案

      1.OpenXmlSDK是个很好的类库,可惜只能通过C#调用,C#的童鞋又福气了. 2.服务端程序由于没法安装office,所以这个对asp.net网站来说是最理想的库了.需要.net 4.0版本 ...

  9. SQL反模式学习笔记13 使用索引

    目标:优化性能 改善性能最好的技术就是在数据库中合理地使用索引.  索引也是数据结构,它能使数据库将指定列中的某个值快速定位在相应的行. 反模式:无规划的使用索引 1.不使用索引或索引不足 2.使用了 ...

  10. Git permission denied(public key) 解决方法

    1. 在Linux上: # ssh-keygen       ##一定用 id_rsa.pub # cat /root/.ssh/id_rsa.pub 2. copy 整个文件内容到剪切板 3. 打开 ...