C++ STL源码分析(二):STL的幕后英雄-----分配器
STL的幕后英雄----分配器allocators
1.由operator new() 和 malloc()讲起
先说一个实际的观念:所有的分配动作,一层一层的下去,C++向下最后都会到c这个level(C runtime memory)所提供的malloc函数,这个函数在根据它是在windows或linux等不同操作系统里面的system api去拿到真正的内存。
1.1new operator 和 operator new
我们平时用来创建新对象的new关键字其实是 new operator;
new operator主要做两件事:1.分配内存; 2.调用类的构造函数
而分配内存的工作,其实就是调用了C++中自带的 operator new函数
下面是vc98中提供的operator new的源码截图:
1.2 malloc
从上面的源码中可以看到,operator new其实就是调用malloc函数来进行内存分配的,下面展示一个malloc分配内存后返回的内存空间模型:
浅蓝色部分为我们所指定的size大小,红色的部分是cookie,而除此之外还有一些overhead。至于这些额外内存的用途会在后面更新一个《C++内存管理》专栏来讲解。
疑问:
这时就有一个小问题,STL中的容器背后的allocators是怎么分配内存的呢?就是单纯的使用malloc嘛?还是有一些独特的trick呢?
2.allocators源码分析
想要解决上面的疑问,只需要找到allocators的源代码然后搞懂它就可以了。
2.1 allocator类
我们以vector为例,找到vector的源代码,可以看到vector模板类的声明中默认是有allocator的。而STL中所有的容器都是如此,他们的模板类中都默认会有allocator这个类。
我们再找到这个allocator类的定义源码:
可以发现分配器最重要的两个函数: deallocate 和 allocate
我们发现allocate中调用了一个叫做 _Allocate的函数,所以再向下追,看一下_Allocate函数做了什么:
这时可以看到,_Allocate函数中就是调用的operator new函数,而前面已经知道了operator new是通过条用malloc来进行内存的分配。同理也能找到 deallocate中调用了_Deallocate函数,而_Deallocate函数中又调用operator delete最终调用free来继续内存的释放。