分配内存池_S_refill源码
大约 2 分钟
分配内存池_S_refill源码
作用:
- 根据
__n
,在_S_free_list
中对应位置的元素指向一个__nobjs
(默认为20)个__n
字节chunk块的内存池 - 并且把第一个
__chunk
块分配出去,并填写剩下所有__chunk
块的next域。
只有从备用内存中分配出来,并挂在_S_free_list
下的,才会填写chunk块头的_M_free_list_link

template <bool __threads, int __inst>
void* __default_alloc_template<__threads, __inst>::_S_refill(size_t __n){
int __nobjs = 20; // 局部变量,内存池中开辟__chunk 块的数量
// 申请__nobjs个__n字节chunk的内存池,__nobjs按引用传入_S_chunk_alloc,__nobjs可能会在_S_chunk_alloc里被修改
// 如果_S_start_free和_S_end_free之间的备用内存不够分配20个__n字节的chunk时,会修改__nobjs
char* __chunk = _S_chunk_alloc(__n, __nobjs);
_Obj* __STL_VOLATILE* __my_free_list;// 二级指针,遍历_S_free_list数组
_Obj* __result;
_Obj* __current_obj;
_Obj* __next_obj;
int __i;
// 当内存池最多只能包含1个__n字节chunk块的时候,直接返回,不需要进入for循环再填写next域
if (1 == __nobjs) return(__chunk);
// _S_freelist_index(__n)返回的是分配的__n字节在_S_free_list的哪个元素中分配
// __my_free_list 指向分配__n字节的元素
__my_free_list = _S_free_list + _S_freelist_index(__n);
/* Build free list in chunk */
// 指向待分配出去的内存块
__result = (_Obj*)__chunk;
// __chunk 是char*,实际上+__n就是越过了一个__chunk块,指向了第二个__chunk 块的起始地址
// __next_obj 和*__my_free_list 都指向第二个块
*__my_free_list = __next_obj = (_Obj*)(__chunk + __n);
// i从1开始,表示__current_obj 一开始就指向第二个__chunk块
// 整个for循环做的就是把内存是填写剩下所有__chunk块的next域
for (__i = 1; ; __i++) {
__current_obj = __next_obj;
__next_obj = (_Obj*)((char*)__next_obj + __n);
//因为每循环依次__i都加1,最后一个下标__i为__nobjs-1
if (__nobjs - 1 == __i) {
// next域填写完成,最后一个__chunk块的next域为0地址
__current_obj -> _M_free_list_link = 0;
break;
} else {
__current_obj -> _M_free_list_link = __next_obj;
}
}
return(__result);
}