C++ STL: 分配器allocators 源码分析

STL 基本的六大组件作用以及功能如下:
在这里插入图片描述
可以看到allocator是数据存储组件container的幕后支持者,负责为其数据存储分配对应的存储空间。

operator::new

在详细介绍alloctor之前,先描述一下new运算符,我们使用C++ new一个对象的时候就是调用底层operator::new运算符,实现如下:

void * operator new(std::size_t size)
{
    ++allocations;
    void * retval = malloc(size);
    if (!retval)
        throw std::bad_alloc();
    return retval;
}

可以看到底层仍然是调用 C 语言的库函数 malloc进行对应存储空间的分配,分配的大小就是我们传入的size,总共size 个bytes的大小。

这里再简单描述一下malloc分配指定size大小的内存空间分布情况如下:`
C++ STL: 分配器allocators 源码分析_第1张图片
可以看到这里malloc分配的物理内存占用实际上还有一些头部和尾部用来对当前内存空间进行管理。

分配器 Allocators

在STL的容器中,基本都会使用相同的allocator函数进行对应内存空间的分配,如下:
C++ STL: 分配器allocators 源码分析_第2张图片
接下来可以看一下对应allocator类的实现:
C++ STL: 分配器allocators 源码分析_第3张图片
其中allocate函数的实现如下:
在这里插入图片描述
可以看到底层调用的还是operator new操作符,同时对应的deallocate函数的底层释放仍然调用的是operator delete,综上从源码的实现上我们可以知道allocator底层仍然调用的是malloc和free进行对应空间的分配和释放。

我们代码中的空间分配和释放 过程可以编写如下代码:

//分配空间,一下allocate的方式是初始化了一个临时对象,调用对应的allocate函数
int *p = allocator<int>().allocate(512,(int*)0);
// 在的释放的时候调用对应的deallocate函数
allocator<int>().deallocate(p,512);

在GNU 2.9-4.9版本之间发生过一些变更
GNU2.9的 defalloc.h关于allocate和deallocate函数的实现如下:
C++ STL: 分配器allocators 源码分析_第4张图片
C++ STL: 分配器allocators 源码分析_第5张图片
看得出来以上都是基于operator new和operator delete进行的封装, 且没有增加自己的设计。

但是2.9版本的并不推荐使用Allocator的实现,想要提升性能,对内存空间有更加合理的管理,所以他们在容器中使用的是自封装的alloc类的实现(stl_alloc.h)。
逻辑结构图如下:
C++ STL: 分配器allocators 源码分析_第6张图片

但是到了GNU4.9 版本之后,allocator的实现又恢复到未经任何封装的new/delete 运算符的实现了。
C++ STL: 分配器allocators 源码分析_第7张图片
当然在4.9之中,也实现了其他的allocator,比如:__pool_alloc
C++ STL: 分配器allocators 源码分析_第8张图片
我们可以在分配空间的时候自己进行指定调用
vector> vec;

你可能感兴趣的:(#,编程语言:C++,#,编程语言C)