STL源码剖析(1)

  近段时间看了侯捷老师的《STL源码剖析》,看第一遍的时候一头雾水,反复多看几遍,似乎明白了一些。因此将学到的知识做一个记录,也算是记录自己的学习过程。本系列博客主要记录一些宏观理解性的东西,具体的代码实现还是要仔细品味原书。

概览

  STL即C++标准模板库,主要由六大部件组成,分别是:分配器、容器、迭代器、算法、仿函数、适配器。这六大部件之间的交互关系表现为:容器通过分配器取得数据存储空间,算法通过迭代器存取容器的内容,仿函数可以协助算法完成不同的策略变化,适配器可以修饰或套接仿函数、迭代器、容器等。
  在讲述这些主要部件之前,先来了解一下面向对象编程和泛型编程,面向对象编程(Object-Oriented programming,简称OOP)企图将数据和处理数据的方法放到一起,例如,在C++的类中,一般会有成员变量和处理成员变量的成员函数,在需要使用的时候创建一个对象,然后以对象来调用它们。而泛型编程(Generic Programming,简称GP)是将数据和处理方法分离开来,这里的处理方法通常是全局函数,例如STL中的算法和容器,两者互不影响,需要的时候通过迭代器来传递信息。
  好了,接下来就从这六大部件出发,了解STL的内部关系。这篇博文主要记录分配器的重点。

分配器(allocators)

  allocator主要是用来管理存储空间,它当中的 allocate() 调用 operator new() 来分配空间,其中 operator new() 中又调用了C语言中的 malloc() 函数,而 deallocate() 则调用了operator delete(),其中,operator delete() 又调用了 free() 来释放内存。以上谈的这种分配器是标准规范下的实现方法。而SGI STL有一种默认的分配器 alloc ,它的每一个容器都已经指定其缺省的空间分配器为 alloc,例如下面的 vector 声明:
template <class T, class Alloc = alloc>
class vector{…};
  这其中就是缺省使用的 alloc 为分配器。由于调用 malloc() 只会寻找整片比较大的空间,对于一些小型区块,可能造成内存浪费的问题,因此,SGI设计了双级分配器,第一级分配器直接使用 malloc() 和 free(),第二级分配器则视情况采用不同的策略:当配置区块超过128字节时,视之为 “足够大”,便调用第一级分配器 ,当分配区块小于128字节时,视之为 “过小”,为了降低额外负担(合理利用资源),就使用第二级分配器。
  而第二级分配器的具体实现是以内存池管理的形式,每次配置一块大内存,然后维护对应的自由链表(可增加,也可删减),下次如果再有相同大小的内存需求,就直接从自由链表中取出,如果使用方释放了小块内存,则由分配器回收到对应的链表中。为了方便管理,SGI的第二级分配器会主动将任何小额区块的内存需求上调至8的倍数(例如使用者需要30字节,就自动调整为32字节),并维护16个自由链表,各自管理的大小分别为:8,16,24,32,40,56,64,72,80,88,96,104,112,128字节的小额区块(例如:第一个链表节点就管理空间内所有大小为8字节的小区快,第二个节点管理所有大小为16字节的小区快,以此类推)。
  因此,整个的内存分配释放过程即可归纳为如下流程:分配器拥有标准接口函数 allocate(),此函数首先判断区块的大小,大于128字节就调用第一级分配器,小于128字节就检查对应的自由链表。如果自由链表内有可用的区块,就直接拿来用,如果没有可用的区块,就将区块大小上调至8的倍数,然后重新填充空间。 在释放的时候,同样由分配器的标准接口函数 deallocate() 首先判断区块大小,大于128字节就调用第一级分配器,小于128字节就找出对应的自由链表,将区块回收。

原文引用 大专栏  https://www.dazhuanlan.com/2019/08/27/5d64c84c4c428/

原文地址:https://www.cnblogs.com/petewell/p/11418625.html

时间: 2024-10-21 15:44:43

STL源码剖析(1)的相关文章

《STL源码剖析》---stl_pair.h阅读笔记

pair是STL中的模板类型,它可以存储两个元素,它也被称作"对组".在map中已经用到了它,pair其实就是一个struct结构,存有两个public的元素,重载了几个运算符,没有什么成员函数,源代码很简单. G++ 2.91.57,cygnus\cygwin-b20\include\g++\stl_pair.h 完整列表 /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy,

《STL源码剖析》---stl_tree.h阅读笔记

STL中,关联式容器的内部结构是一颗平衡二叉树,以便获得良好的搜索效率.红黑树是平衡二叉树的一种,它不像AVL树那样要求绝对平衡,降低了对旋转的要求,但是其性能并没有下降很多,它的搜索.插入.删除都能以O(nlogn)时间完成.平衡可以在一次或者两次旋转解决,是"性价比"很高的平衡二叉树. RB-tree(red black tree)红黑树是平衡二叉树.它满足一下规则 (1)每个节点不是红色就是黑色. (2)根节点是黑色. (3)如果节点为红色,则其子节点比为黑色. (4)任何一个节

《STL源码剖析》---stl_iterator.h阅读笔记

STL设计的中心思想是将容器(container)和算法(algorithm)分开,迭代器是容器(container)和算法(algorithm)之间的桥梁. 迭代器可以如下定义:提供一种方法,能够依序寻访某个容器内的所有元素,而又无需暴露该容器的内部表达方式. 在阅读代码之前,要先了解一个新概念:Traits编程技法 template <class T> struct MyIter { typedef T value_type //内嵌型别声明 T *ptr; MyIter(T *p = 0

STL 源码剖析 算法 stl_algo.h -- search_n

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie search_n ---------------------------------------------------------------------------------------- 描述:在序列[first, last) 所涵盖的区间中,查找"连续 count 个符合条件之元素"所形成的子序列, 并返回迭代器 last 思路: 1.首先找出 value 第一次出现点

STL 源码剖析 算法 stl_algo.h -- lower_bound

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie lower_bound(应用于有序区间) -------------------------------------------------------------------------------------------------------------------------- 描述:二分查找,返回一个迭代器指向每一个"不小于 value "的元素, 或 value 应该

STL 源码剖析 算法 stl_algo.h -- upper_bound

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie upper_bound(应用于有序区间) ------------------------------------------------------------------------------------------------------------------------------------------------- 描述:受STL区间前闭后开习惯的影响,upper_boun

STL 源码剖析 算法 stl_algo.h -- binary_search

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie binary_search ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 描

STL 源码剖析 算法 stl_algo.h -- next_permutation

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie next_permutation ----------------------------------------------------------------------- 描述: 取得 [first, last) 所标示之序列的下一个排列组合.如果没有,返回 false,有,返回true 思路: 从后往前 1.找两个相邻元素,令左端的元素为*i,右端的元素为*ii,且满足 *i <

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

前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配置器,配置的对象,是内存.(以下内容来自<STL源码剖析>) 空间配置器的标准接口 根据STL的规范,allocator的必要接口 各种typedef 1 allocator::value_type 2 allocator::pointer 3 allocator::const_pointer 4

STL&quot;源码&quot;剖析-重点知识总结

STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合套用: 容器(Containers):各种数据结构,如:vector.list.deque.set.map.用来存放数据.从实现的角度来看,STL容器是一种class template. 算法(algorithms):各种常用算法,如:sort.search.copy.erase.从实现的角度来看,STL算法