网上有很多对于STL空间配置器源码的剖析,之所以这么多人去剖析空间配置器,我觉得是真的设计的太好,而且剖析空间配置器的架构的设计对于C++学者来说是一个不错的提高能力的项目,所以加入到这个解剖大军中来。
参照了侯捷的《STL源码剖析》,原本直接看源码不懂得东西,突然间豁然开朗。再次写下自己对于STL空间配置器的一点点理解。
要了解空间配置器,有一张图是必看的:
这张图是一级空间配置器宇二级空间配置器的封装方式与调用。从此图我们们可以看到其实空间配置器是分为两级的,而这里所谓的两级并没有高低之分,它们之间的区别就是看你想要申请内存空间的大小。如果申请的内存大小超过128,那么空间配置器就自动调用一级空间配置器。反之调用二级空间配置器。而且在这里要说明的是空间配置器默认使用的是一级空间配置器。
一. 一级空间配置器:
一级空间配置器就比较简单了,STL源码中的一级空间配置器命名为class __malloc_alloc_template ,它很简单,就是对malloc,free,realloc等系统分配函数的一层封装,我向这也是为什么这么取名的原因。
源码中的一级空间配置器也不难看懂,懂了他的思想也就不难写出如下的代码:
<span style="font-family:Microsoft YaHei;font-size:14px;">template<int inst>//非类型模板参数
class MallocAllocTemplate//一级空间配置器(malloc,free,realloc)
{
public:
static void* Allocate(size_t n)
{
void* ret = malloc(n);
if (0 == ret)
ret = OomMalloc(n);
return ret;
}
static void Deallocate(void* p)
{
free(p);
}
static void* Reallocate(void* p, size_t newsize)
{
void* ret = realloc(p, newsize);
if (ret == 0)
ret = OomRealloc(p, newsize);
return ret;
}
private:
static void* OomMalloc(size_t n)//调用自定义的句柄处理函数释放并分配内存
{
ALLOC_FUN hander;
void* ret;
while (1)
{
hander = MallocAllocHander;
if (0 == hander)
{
cout << "Out of memory" << endl;
exit(-1);
}
hander();
ret = malloc(n);
if (ret)
{
rteurn (ret);
}
}
}
static void* OomRealloc(void* p, size_t newsize)//同上
{
ALLOC_FUN hander;
void* ret;
while (1)
{
hander = MallocAllocHander;
if (0 == hander)
{
cout << "Out of memory" << endl;
exit(-1);
}
hander();
ret = realloc(p,newsize);
if (ret)
{
rteurn(ret);
}
}
}
static void(*SetMallocHandler(void(*f)()))();//设置操作系统分配内存失败时的句柄处理函数
static ALLOC_FUN MallocAllocHander;
};
template<int inst>
ALLOC_FUN MallocAllocTemplate<inst>::MallocAllocHander = 0;//句柄函数初始化为0</span>
一级空间配置器中没有可以讨论的,除了这个句柄函数:static void(*SetMallocHandler(void(*f)()))();对于一个C初学者来说想要看懂这个声明有点难度,这是一个返回值,参数都为函数指针的一个函数指针。填起来有点绕,其实他就是一个函数指针,它指向的是一个句柄函数,这个句柄函数对于一级空间配置器是比较重要的。
malloc,free,realloc等库函数是向系统申请内存并且操作的函数。平时我们并不太会遇到内存空间分配不出来的情况,但是如果这一套程序是运行在服务器上的,各种各样的进程都需要内存。这样频繁的分配内存,终有一个时候,服务器再也分配不出内存,那么空间配置器该怎么办呢?这个函数指针指向的句柄函数就是处理这种情况的设计。
MallocAllocHander()一般是自己设计的一种策略。这种策略想要帮助操作系