内存池allocate分配过程
大约 2 分钟
内存池allocate分配过程
根据想分配的内存大小,先定位到_S_free_list
相应的元素__my_free_list
(总共16个元素)
如果
__my_free_list
下没有挂着空闲的chunk块,那直接从备用内存或者使用malloc申请chunk块,然后分配空间如果还有空闲的chunk块,那就使得
_S_free_list
相应的元素指向__my_free_list
下面挂着的下一块空闲的内存块,然后把前一块内存分配出去

template <bool threads, int inst>
class __default_alloc_template {
//...
class _Lock;
friend class _Lock;
class _Lock { //出作用域自动解锁
public:
_Lock() { __NODE_ALLOCATOR_LOCK; } //构造函数加锁
~_Lock() { __NODE_ALLOCATOR_UNLOCK; } //析构函数解锁
};
/* __n must be > 0 */
static void* allocate(size_t __n)
{
void* __ret = 0;
if (__n > (size_t) _MAX_BYTES) { //enum {_MAX_BYTES = 128};
//超过128字节,使用一级空间配置器,底层malloc方法开辟内存
__ret = malloc_alloc::allocate(__n);
}
else { //小于128则通过内存池管理
//定义一个指针指向__n个字节应该在内存池哪个块分配
_Obj* __STL_VOLATILE* __my_free_list
= _S_free_list + _S_freelist_index(__n);
#ifndef _NOTHREADS
//对于自由链表的增删改要加锁,不是线程安全的
_Lock __lock_instance;
#endif
//result为第一个chunk块地址
_Obj* __RESTRICT __result = *__my_free_list;
if (__result == 0)
//若__result下没有挂着空闲的chunk块,
//_S_refill直接构造chunk后分配,
//_S_round_up(__n)指的是内存池每个块的大小,
__ret = _S_refill(_S_round_up(__n));
else {//如果不为空,则ret指向链表的第一个节点
//因为第一个chunk块要被分配出去了,
//也就是_S_free_list的元素直接指向后面的节点
*__my_free_list = __result -> _M_free_list_link;
__ret = __result;// 这时候是要把__result分配出去
}
}
return __ret;
};
};