前言

上一节我们分析了空间配置器对new的配置, 而STL将空间配置器分为了两级, 第一级是直接调用malloc分配空间, 调用free释放空间, 第二级三就是建立一个内存池, 小于128字节的申请都直接在内存池申请, 不直接调用mallocfree.

本节我们就先分析第一种空间配置器, 直接调用malloc, free, 而STL有是怎样的封装处理.

一级配置器

一级配置器的类. 它无template型别参数. 这里我将public定义的函数和私有成员函数成对分离出来讲解.

// 一级配置器
template <int inst>
class __malloc_alloc_template
{
// 这里private里面的函数都是在内存不足的时候进行调用的
private:
static void *oom_malloc(size_t); // 分配不足
static void *oom_realloc(void *, size_t); // 重新分配不足
#ifndef __STL_STATIC_TEMPLATE_MEMBER_BUG
static void (* __malloc_alloc_oom_handler)(); // 内存不足设置的处理例程, 默认设置的是0, 表示没有设置处理例程, 这个处理例程是由用户手动设置的
#endif
public:
};

唯一比较麻烦的就是set_malloc_handler 它就是接受一个函数指针, 用来保存用户自定义的处理函数, 如果用户没有设置的话, 默认就设置为0. 因为处理函数会跟后面的内存不足有关系.

// 这里是模仿c++的set_new_handler. 是由用户自己定义的处理函数, 没有设置默认为0
static void (* set_malloc_handler(void (*f)()))()
{
void (* old)() = __malloc_alloc_oom_handler;
__malloc_alloc_oom_handler = f;
return(old);
}

默认将处理例程设置为0, 只有用户自己设置.

template <int inst>
void (* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0;

allocate

allocate : 很明显, 这里直接调用malloc分配内存, 当内存不足的时候, 程序继续调用oom_malloc来选择抛出异常还是一直申请内存, 直到申请内存成功.

// 在分配和再次分配中, 都会检查内存不足, 在不足的时候直接调用private中相应的函数
static void * allocate(size_t n)
{
void *result = malloc(n);
if (0 == result) result = oom_malloc(n);
return result;
}

oom_malloc函数功能 : 除非用户自定义了处理例程, 否则当内存不足的时候直接输出内存不足的提示然后直接调用exit(1);

用户定义了处理程序, 函数会一直进行内存申请, 直到申请到内存为止

template <int inst>
void * __malloc_alloc_template<inst>::oom_malloc(size_t n)
{
void (* my_malloc_handler)();
void *result;
// 用户自定义处理例程, 就一直申请内存, 否则抛出异常
for (;;)
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
(*my_malloc_handler)();
result = malloc(n);
if (result) return(result);
}
}

deallocate

一级配置器直接调用free释放内存

static void deallocate(void *p, size_t /* n */)
{
free(p);
}

reallocate

下面的函数都是很简单的或是重复的功能, 就一笔带过.

这里reallocate和oom_realloc和上面allocate一样的, 这里就不做过多的解释了.

static void * reallocate(void *p, size_t /* old_sz */, size_t new_sz)
{
void * result = realloc(p, new_sz);
if (0 == result) result = oom_realloc(p, new_sz);
return result;
}
template <int inst>
void * __malloc_alloc_template<inst>::oom_realloc(void *p, size_t n)
{
void (* my_malloc_handler)();
void *result; for (;;) {
my_malloc_handler = __malloc_alloc_oom_handler;
if (0 == my_malloc_handler) { __THROW_BAD_ALLOC; }
(*my_malloc_handler)();
result = realloc(p, n);
if (result) return(result);
}
}

程序默认定义mallo_alloc函数, 并且设置统一的调用接口, 默认的的接口为第二级配置器

// 默认将malloc_alloc设为0;
typedef __malloc_alloc_template<0> malloc_alloc;

统一的接口

定义符合STL规格的配置器接口, 不管是一级配置器还是二级配置器都是使用这个接口进行分配的

// 定义符合STL规格的配置器接口, 不管是一级配置器还是二级配置器都是使用这个接口进行分配的
template<class T, class Alloc>
class simple_alloc {
public:
static T *allocate(size_t n)
{ return 0 == n? 0 : (T*) Alloc::allocate(n * sizeof (T)); }
static T *allocate(void)
{ return (T*) Alloc::allocate(sizeof (T)); }
static void deallocate(T *p, size_t n)
{ if (0 != n) Alloc::deallocate(p, n * sizeof (T)); }
static void deallocate(T *p)
{ Alloc::deallocate(p, sizeof (T)); }
};

总结

本节对STL的第一级配置器做了分析, STL对malloc和free用函数重新进行了封装, 同时一级还是二级都做了统一的接口. 接下来我们继续分析第二级配置器.

STL源码分析之第一级配置器的更多相关文章

  1. STL源码分析之第二级配置器

    前言 第一级是直接调用malloc分配空间, 调用free释放空间, 第二级三就是建立一个内存池, 小于128字节的申请都直接在内存池申请, 不直接调用malloc和free. 本节分析第二级空间配置 ...

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

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

  3. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  4. 《STL源码剖析》——第一、二、三章

     第一章:概论: 换句话说,STL所实现的,是依据泛型思维架设起来的一个概念结构.这个以抽象概念(abstract concepts)为主体而非以实际类(classes)为主体的结构,形成了一个严谨的 ...

  5. 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入

    使用react全家桶制作博客后台管理系统   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...

  6. STL源码分析《4》----Traits技术

    在 STL 源码中,到处可见 Traits 的身影,其实 Traits 不是一种语法,更确切地说是一种技术. STL库中,有一个函数叫做 advance, 用来将某个迭代器(具有指针行为的一种 cla ...

  7. STL源码分析《3》----辅助空间不足时,如何进行归并排序

    两个连在一起的序列 [first, middle) 和 [middle, last) 都已经排序, 归并排序最核心的算法就是 将 [first, middle) 和 [middle, last) 在  ...

  8. STL 源码分析《1》---- list 归并排序的 迭代版本, 神奇的 STL list sort

    最近在看 侯捷的 STL源码分析,发现了以下的这个list 排序算法,乍眼看去,实在难以看出它是归并排序. 平常大家写归并排序,通常写的是 递归版本..为了效率的考虑,STL库 给出了如下的 归并排序 ...

  9. STL——空间的配置和释放std::alloc(第一级配置器和第二级配置器)

    1 空间的配置和释放,std::alloc 对象构造前的空间配置和对象析构后的空间释放,由<stl_alloc.h>负责,SGI对此的设计哲学如下: 向system heap要求空间 考虑 ...

随机推荐

  1. 在win10下改变默认的输入法切换Ctrl+Space

    在win10下改变默认的输入法切换Ctrl+Space 学习了:https://www.zhihu.com/question/22288432 在win10下面,有两种风格的控制面板设置: 在输入法上 ...

  2. 微信的token验证

    微信的token验证 在微信公众平台的基本配置中,需要输入token,这个token不是那个access_token springmvc验证代码: @RequestMapping(value=&quo ...

  3. jsp上传下载+SmartUpload插件上传

    使用之前须要自己下载jspSmartUpload.jar包 这里找到一个支持中文的jar包,下载地址例如以下: http://www.blogjava.net/Files/hijackwust/jsm ...

  4. UNP(一):网络编程角度下的TCP、UDP协议

    此博文是学习UNP(UNIX Network Programming)后的读书笔记,供以后自己翻阅回想知识. TCP.UDP概述 在前面<计算机网络与TCP/IP>栏目下已经介绍过一些关于 ...

  5. Codeforces Round #306 (Div. 2) A

    题意 给一个字符串(长度<=10^5).问当中有没有一个"BA"和一个"AB"呢?假设都有而且它们不反复(即ABA不算),输出YES.否则输出NO. 思路 ...

  6. 如何将unity资源窗体中的文件一下所有折叠/打开

    1.选中父物体 2.按住alt 3.再按下键盘上的左键/右键:此父物体下的所有折叠/打开 或者 alt + LMB  点击所要折叠/打开的父物体左边的小三角

  7. wesome-android

    awesome-android Introduction android libs from github System requirements Android Notice If the lib ...

  8. Power Network(最大流(EK算法))

    http://poj.org/problem?id=1459 题意:有一个电路网络,每个节点可以产生.传递.消耗若干电量,有点线连接结点,每个电线有最大传输量,求这个网络的最大消费量. 思路:从源点到 ...

  9. selenium3 + python - cookie定位

    from selenium import webdriverfrom selenium.webdriver.support.wait import WebDriverWaitimport time d ...

  10. Speex回声消除原理深度解析

    这里假设读者具有自适应滤波器的基础知识.Speex的AEC是以NLMS为基础,用MDF频域实现,最终推导出最优步长估计:残余回声与误差之比.最优步长等于残余回声方差与误差信号方差之比,这个结论可以记下 ...