要看STL源码,从这里开始吧

本文深入剖析STL中的内存配置器原理,介绍如何利用内存池思想提高内存分配效率,减少内存碎片。并提供了内存配置器的具体实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

你有没这样的经历,想去看STL源码,浏览了几页后,发现犯困,便又放到了一边。我也这样过,但一个偶然的机会,我学习了内存池,突然发现STL也有这样的东西,便再拿起尘封已久的STL源码,发现能看懂了。所有,让我带你突破STL源码的大门吧!

为什么要使用空间配置器呢?如果你学过C++,那你一定懂得,当需要分配内存便使用new和delete,也可以使用malloc和free,不过malloc是不会触发构造函数的调用。内存配置器其实也是调用这些来分配内存,只是它对分配好的内存做了进一步的处理才给我们用,让你程序更高效。下面通过分析STL源码解析文档的第二章—空间配置器。帮你打开STL源码的大门,也让你理解内存配置器,大家都叫它内存池。

 先说说STL空间配置器的总体概念吧:先分配一个大的内存空间(malloc),然后把此块内存分成更小的一块一块,程序需要内存空间时,不再是使用new或malloc,而是直接从内存配置器中拿取一块空闲的内存块,程序释放内存时,是把内存块放回内存配置器。整个过程只使用一次malloc分配,之后的所有操作都是在这大块内存中进行。这样便更高效,也能减少内存碎片。其实这就是内存池的思想。后面我会为大家分析一个内存池的实现。只要你明白了这个原理,往下看就简单点了。首先你得下载一个高清的有目录的STL源码文档。

地址:http://download.youkuaiyun.com/detail/wulang150/8122917

 

从这里开始,让你能更好的理解STL空间配置器是怎样使用上面的原理想法的。STL采用两级配置器,第一级配置器就是直接向操作系统申请内存,看源码,可以看到使用的是malloc,没骗你吧!

第二级配置器就深深地体现了上面所说的内存池原理,先分配一块大内存,再把此块内存分成一小块一小块。看图。


上图他妈画得太好了。是不是看到那大块内存被分成了许多小块,并且它们用链表组织起来,从链表头取,用完又放回链表头。STL维护了数个这样的链表,基本原理不变。这里说说,第二级配置器的那块大内存是通过一个函数获得,其实也是调用malloc,只是它在提供给free_list内存的时候,多做了很多处理,STL也叫它为内存池。说白了,第二级配置器就是链表+内存池的组合,程序直接从链表头拿内存,链表没内存了,便想内存池申请,内存池没内存了就调用malloc。

 读到这里,你应该比较清楚了解内存配置器的原理了吧。好吧,现在看看STL提供的内存配置函数接口。它提供什么接口让我们向它申请内存,又用什么接口给我们释放呢?

写得太明显了,allocate()是申请内存,deallocate()是释放内存。似乎在向你呼叫,以后要用内存,别再用new或malloc了,用我吧—allocate()。

Allocate()部分内部的实现:

可以看到,分配的内存大于128就调用第一级配置器,其他都是调用二级,大家有没看到free list的身影。释放的我就不说了,自己去看。你别以为看了这篇文章就懂了空间配置器,必须的自己去看,去体会,文章只是个引导,让你下次看STL源码不再卡在第二章。

 为了让大家进一步理解内存配置器,下面就为大家提供一段内存池的代码,你可以拿代码去调用,也可以拿来使用。我就经常在公司项目中使用。效果刚刚的,其中的Pool.h的内存池是我经常使用,里面有注释,你看得懂的。具体怎么用?简单说说吧

下载:http://download.youkuaiyun.com/detail/wulang150/8123733

 

先#include “Pool.h”

Pool  myMem;

//Node *s = new Node();  //注释的代码,原本要使用new的,后来改为内存池提供

Node *s = (Node *) myMem.Alloc();   //申请

memset(s,0,sizeof(Node));

new(s)  Node();      //调用对象的构造函数


 p->~Node();               //调用析构函数

myMem.Free(p);   //释放


 申请到内存后,记得要调用构造函数哈,释放内存前记得要调用析构函数。这些东西在STL源码也有说明:

构造使用construct,析构使用destroy,这两个东西,到你看vector源码便会发现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值