SGI STL空间配置器源码刨析

SGI STL空间配置器源码刨析

SGI STL一级空间配置器和二级空间配置器,一级allocator采用malloc和free管理内存,二级是基于内存池实现的。

SGI STL 对于容器空间配置器选择

template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class vector;

对于vector使用的默认空间配置器__STL_DEFAULT_ALLOCATOR,就是下面这两个宏定义的allocator 和 alloc。

#   ifdef __STL_USE_STD_ALLOCATORS // 使用STL标准的(STD)的空间配置器,一级空间配置器 alloator
#     define __STL_DEFAULT_ALLOCATOR(T) allocator< T >
#   else 					     // 否则使用二级空间配置器 alloc
#     define __STL_DEFAULT_ALLOCATOR(T) alloc
#   endif
一级空间配置器
template <int __inst>
class __malloc_alloc_template; // 主要的类
二级空间配置器
typedef __default_alloc_template<__NODE_ALLOCATOR_THREADS, 0> alloc; 

可以看到SGI STL默认使用的是二级空间配置器,另外__NODE_ALLOCATOR_THREADS在宏默认是true,所以SGI STL的容器空间配置器默认是线程安全的,在下面的代码中大家就可以看到。

template <bool threads, int inst>
class __default_alloc_template; // 主要的类

SGI STL一级空间配置器 (allocator)

template <class _Tp>
class allocator
{
   
typedef alloc _Alloc; 
    
public:
     // allocator实现
     _Tp* allocate(size_type __n, const void* = 0) 
     {
   
    	return __n != 0 ? static_cast<_Tp*>(_Alloc::allocate(__n * sizeof(_Tp))) : 0;
     }

    // deallocator实现
  	void deallocate(pointer __p, size_type __n)
    {
   
        _Alloc::deallocate(__p, __n * sizeof(_Tp));
    }
    
    // construct实现
    void construct(pointer __p, const _Tp& __val) 
    {
    
        new(__p) _Tp(__val); // 定位new
    }
    
    // destroy实现 
    void destroy(pointer __p)
    {
   
        __p->~_Tp();   
    }
};

可以看出SGI STL的一级空间配置器的construct和destroy的实现和c++标准库STL中的一级空间配置器相同

在对上面的 alloc 进行深入查看

typedef malloc_alloc alloc;  // 在查看malloc_alloc实现
typedef __malloc_alloc_template<0> malloc_alloc; 
// 在对 __malloc_alloc_template 查看,实现如下

template <int __inst>
class __malloc_alloc_template 
{
   
public:
    static void* allocate(size_t __n)
    {
   
        void* __result = malloc(__n);
    	if (0 == __result) __result = _S_oom_malloc(__n);
    	return __result;
  	}

  	static void deallocate(void* __p, size_t /* __n */)
  	{
   
    	free(__p);
  	}
};

最终可以看到,allocate的底层实现就是malloc,deallocate的底层实现就是调用free,和C++标准STL库的底层实现一样。

SGI STl 的二级空间配置器

重要的一些定义
 enum {
   _ALIGN = 8};       // 内存对齐大小,也就是chunk块之间的增长大小8,16,24,...
 enum {
   _MAX_BYTES = 128}; // 最大的chunk块的字节数 
 enum {
   _NFREELISTS = 16}; // _MAX_BYTES/_ALIGN // 共有多少不同大小的chunk块,128/8 = 16
union _Obj 
{
   
    union _Obj* _M_free_list_link; // 自由链表的指针
    char _M_client_data[1];  
}; // chunk块的信息,
static _Obj* __STL_VOLATILE _S_free_list[_NFREELISTS]; // 管理自由链表的数组,如下图所示,类似于Glibc
// 数组中的成员都是__Obj*,每个指针都被赋值为0
// 对于数组使用volatile修饰,确保多线程环境中,对于每个线程都是可见的。

template <bool __threads, int __inst>
typename __default_alloc_template<__threads, __inst>::_Obj* __STL_VOLATILE
__default_alloc_template<__threads, __inst> ::_S_free_list[
# if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC)
    _NFREELISTS
# else
    __default_alloc_template<__threads, __inst>::_NFREELISTS
# endif
] = {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // 全为0

在这里插入图片描述

// Chunk allocation state. 记录chunk块的信息
static char* _S_start_free;
static char* _S_end_free;
static size_t _S_heap_size;

// chunk块的三个状态的初始值都为0
template <bool __threads, int __inst>
char* __default_alloc_template<__threads, __inst>::_S_start_free = 0;

template <bool __thre
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值