STL源码阅读(1)--allocator配置器

STL源码阅读(1)–allocator配置器

STL的容器都是通过模板实现的,而每个目标的模板类型中会存在一个"typename _Alloc",如vector中的
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >。

这个“typename _Alloc”是什么?意义是什么?
_Alloc是一个allocator类型,用于指定使用那种allocator获取数据存储空间。

vector的template<typename _Tp, typename _Alloc = std::allocator<_Tp> >说明默认指定的allocator是std::allocator。

综上,在阅读容器代码前,我们先了解下allocator的实现。

1. allocator配置器功能

负责空间配置和管理。从实现来看,是一个实现了动态空间配置、空间管理、空间释放的类模板。容器通过allocator配置器来获取数据存储空间。

2. alloctor分类

STL根据不同的应用,C++定制了不同的allocator配置器
/
scoped_allocator
array_allocator
bitmap_allocator:基于cache
debug_allocator:用于debug
extprt_allocator
malloc_allocator:封装malloc和free函数
mt_allocator:多线程相关,基于cache
new_allocator:封装 new和delete
pool_allocator:基于cache
throw_allocator:用于异常
uses_allocator

///

3. alloctor实现

标准allocator
STL的标准接口std::allocator定义在bits/allocator.h文件中,代码为:

      template \<typename _Tp\>
        class allocator: public __allocator_base<_Tp>
        {
         }

allocator继承自__allocator_base,在平台相关的头文件x86_64-redhat-linux\bits\c++allocator.h中有如下定义:

    #if __cplusplus >= 201103L
    namespace std
    {
  
      template<typename _Tp>
        using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
    }
    #else
    #define __allocator_base  __gnu_cxx::new_allocator
    #endif

因此,标准的allocator实际是new_allocator。根据C++标准,STL的allocator,把对象的申请和释放分成4步:
1、申请内存空间
2、执行构造函数
3、执行析构函数
4、释放内存空间

在ext/new_allocator.h中对应封装了4个接口:
allocate()
construct()
destroy()
deallocate()

pointer allocate(size_type __n, const void* = 0)
 { 
	if (__n > this->max_size())
	  std::__throw_bad_alloc();

	return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
 }
 void deallocate(pointer __p, size_type)
      { ::operator delete(__p); }

#if __cplusplus >= 201103L
      template<typename _Up, typename... _Args>
      void construct(_Up* __p, _Args&&... __args)
	{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

      template<typename _Up>
        void 
        destroy(_Up* __p) { __p->~_Up(); }
#else
      void construct(pointer __p, const _Tp& __val) 
      { ::new((void *)__p) _Tp(__val); }

      void 
      destroy(pointer __p) { __p->~_Tp(); }
#endif

从代码来看:
allocate()通过封装全局的operator new来分配内存。
deallocate()通过封装全局的operator delete来释放内存。
construct()通过封装全局的placement new来构造对象。
destroy()通过调用析构函数析构对象。

其他的allocator的实现大体类似。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值