STL源代码剖析(一) - 内存分配

Allocaor

allocator 指的是空间配置器,用于分配内存。
STL中默认使用SGI STL alloc作为STL的内存分配器,尽管未能符合标准规格,但效率上更好。
SGI STL也定义有一个符合标准,名为allocator的配置器,但SGI自己从未使用过它,主要原因是它仅仅把C++的new操作符和delete操作符做了一层薄薄的封装。

C++的new操作符和delete操作符进行内存配置时,new:先配置内存,然后构造对象。delete:先析构对象,然后释放内存。SGI STL将内存配置、释放内存与构造、析构分开。前者由<stl_alloc.h>中的allocate()和deallocate()负责,后者由<stl_construct.h>中的construct()和destroy()负责。 这两个头文件包括于<memory>中(STL标准规定,配置器定义在memory中)。同一时候<memory>还包括了一个文件<stl_unitialized.h>,定义了一些全局函数用来填充、复制大块内存数据。

STL allocator中,alloc::allocate负责内存配置,alloc::deallocate负责内存释放,alloc::construct负责对象构造,alloc::destroy负责对象析构。

SGI对空间的配置与释放的设计哲学:
1.向system heap要求空间;
SGI底层用的malloc和free完毕内存的配置和释放。
2.考虑多线程状态;

3.考虑内存不足时的应变措施;
4.考虑过多“小型区块”可能造成的内存碎片问题。
SGI设计了双层级配置器,第一级直接使用malloc和free,第二级配置器则视情况採用不同的策略:当配置区块超过128bytes时,视之为“足够大”,调用第一级配置器,当小于128bytes时,视之“过小”,为了减少额外负担,便採用复杂的memory pool方式,不再求助于第一级适配器。

一二级配置器关系例如以下

第一级配置器以malloc(),free(),realloc()等c函数运行实际的内存配置,释放,重配置操作,并实现相似 C++ new handler的机制(不能使用C++ new handler的原因时它并不是使用operator new 来配置内存)。

小额区块带来的事实上不仅时内存碎片,配置时的额外负担也是一个大问题,额外负担无法避免。
第二层配置器:假设区块勾搭,超过128bytes时,就移交第一层配置器处理,当区块小于128bytes时则以内存池管理。

内存基本处理工具

STL定义的五个全局函数
construct() - 构造
destroy() - 析构
uninitialized_copy(),uninitialized_fill(),uninitialized_fill_n() - 范围拷贝构造

关于拷贝构造的三个函数,可以将内存的配置与对象的构造行为分离。假设作为输入目的地的[result, result + (last-first)]范围内的每个迭代器都指向未初始化的区域,则uninitialized_copy()使用copy constructor,将输入来源范围内每个对象产生一份复制品,放进输出范围中。

容器的全区间构造函数通常以两个步骤完毕:
1.配置内存区块,是以包括范围内的全部元素;
2.使用uninitialied_copy(),在该内存区块上构造元素。

它们负责在已分配好的空间进行构造。C++标准要求uninitialized_copy具有"commit or rollback"语义:要么做完,要么不做。

在详细的实现中,这三个函数也用到了traits技法,通过traits萃取出元素的特性,假设是POD(Plain Old Data)型别,说明其拥有trivial ctor/ dtor/ copy/ assignment函数,因此可以使用copy()、fill()、fill_n()等算法,假设不是POD型别就仅仅可以循环调用construct()函数了。

參考

<<STL源代码剖析>> 侯捷译

时间: 2024-10-13 08:27:11

STL源代码剖析(一) - 内存分配的相关文章

《STL源代码剖析》---stl_deque.h阅读笔记(2)

看完,<STL源代码剖析>---stl_deque.h阅读笔记(1)后.再看代码: G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_deque.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation f

STL源代码剖析——基本算法stl_algobase.h

前言 在STL中.算法是常常被使用的,算法在整个STL中起到很关键的数据.本节介绍的是一些基本算法,包括equal.fill.fill_n,iter_swap.lexicographical_compare.max,min.mismatch,swap,copy,copy_backward.copy_n.当中一个比較重要的算法就是copy.针对copy的剖析在源代码中能够看到具体的注解. 本文剖析的源代码出自SGL STL中的<stl_algobase.h>文件. 基本算法剖析 #ifndef

STL源代码剖析——STL算法之set集合算法

前言 本节介绍set集合的相关算法,各自是并集set_union,差集set_difference,交集set_intersection 和对称差集set_symmetric_difference.这是个函数都提供了两个版本号的函数原型:第一个版本号是採用默认的排序比較方式operator<:第二个版本号是用户通过仿函数comp自行指定排序方式.注意:这四个算法接受的输入区间都是有序的,输出也是有序的. 以下对set算法进行剖析,详细凝视详见源代码,同一时候给出样例说明该算法的功能.本文源代码摘

解析STL中典型的内存分配

1 vector 在C++中使用vector应该是非常频繁的,但是你是否知道vector在计算内存分配是如何么? 在c++中vector是非常类似数组,但是他比数组更加灵活,这就表现在他的大小是可以自动分配的,就是当你的数据量增大的时候,自动的为你分配空间,当你的分配的大小不够的时候,他就会在分配的内存后边增加2倍大小的空间, vector增加的空间是连续的,因此这个就涉及到了,当你在后边的空间不够的时候,那么计算机就会把你的数据copy一份空间更大的地方来给你分配足够的空间,这,就给计算机带来

STL 源代码剖析 算法 stl_algo.h -- inplace_merge

本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie inplace_merge(应用于有序区间) -------------------------------------------------------------------- 描写叙述:假设两个连接在一起的序列[first, middle)和 [middle, last]都已排序, 那么 inplace_merge 可将它们结合成单一一个序列,并仍有序. 源代码: template

STL源代码剖析 容器 stl_stack.h

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie stack ------------------------------------------------------------- stack 是一种配接器(adapter).以某种容器作为底部结构,改变其接口,使之符合"先进后出"的特性. SGI STL 默认以 deque 为 stack 底部结构 没有遍历行为,没有遍历器 演示样例: #include <stack

STL 源代码剖析 算法 stl_algo.h -- search

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search ------------------------------------------------------------------------- 描写叙述:在序列一[first1, last1) 所涵盖的区间中.查找序列二[first2, last2) 的首次出现点. 思路: 1.遍历序列二 2.假设两序列的当前元素一样,都前进 1 3.否则序列二的迭代器又一次指向開始元素

STL 源代码剖析 算法 stl_algo.h -- equal_range

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie equal_range(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------------------- 描写叙述:利用二分查找找到一个区间,区间里的全部值都等于给定值,返回的是一个pa

STL源代码剖析 容器 stl_vector.h

本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie vector ---------------------------------------------------------------------- 描写叙述: 1.迭代器 vector 维护的是一个连续线性空间.它的迭代器是普通指针. 能满足 RandomAccessIterator 全部必要条件:operator*, operator->,operator++,operator-