源码剖析STL内存分配器 std::allocator,让你能硬刚面试官

本期主要讲解C++ STL中的内存分配器std::allocator及其特性萃取器__gnu_cxx::__alloc_traits

为防止混淆,规定如下:

  • allocator:泛指内存分配器,仅仅是一个术语。
  • std::allocator:是STL实现的内存分配器类std::allocator

更多硬核知识,欢迎关注:

__gnu_cxx::new_allocator

C++的默认的内存分配器std::allocator,继承至__gnu_cxx::new_allocator。而 __gnu_cxx::new_allocator 主要完成两个任务:

  • 分配对象内存、初始化对象
  • 析构对象、释放对象内存

__gnu_cxx::new_allocator 是个空类,没有成员变量,主要有四种成员函数完成上述任务:

  • allocate 函数,用于分配内存
  • construct函数,调用已分配内存对象的构造函数
  • destroy函数,调用析构函数
  • deallocate函数,用于释放内存

__gnu_cxx::new_allocator 的整体框架大致如下:

  template <typename _Tp>
  class new_allocator
  {
   
  public:
    typedef size_t      size_type;
    typedef ptrdiff_t   difference_type;
    typedef _Tp*        pointer;
    typedef const _Tp*  const_pointer;
    typedef _Tp &       reference;
    typedef const _Tp & const_reference;
    typedef _Tp         value_type;

    template <typename _Tp1>
    struct rebind
    {
   
      typedef new_allocator<_Tp1> other;
    };

    new_allocator() _GLIBCXX_USE_NOEXCEPT {
   }
    new_allocator(const new_allocator &) noexcept {
   }
    template <typename _Tp1>
    new_allocator(const new_allocator<_Tp1> &) noexcept {
   }
    ~new_allocator() noexcept {
   }
 
    pointer allocate(size_type __n, const void * = static_cast<const void *>(0));
      
    void deallocate(pointer __p, size_type);
      
    size_type max_size() const noexcept;

    template <typename _Up, typename... _Args>
    void construct(_Up *__p, _Args &&...__args) 
      				noexcept(noexcept(::new ((void *)__p)_Up(std::forward<_Args>(__args)...)));
    template <typename _Up>
    void destroy(_Up *__p) noexcept(noexcept(__p->~_Up()));
    //...
  };
allocate

allocate函数,用于分配大小为__n个字节内存,返回值是分配所得内存的地址。

  • 如果待分配内存大小__n大于当前进程最大可用内存,那么就会抛出bad_alloc异常。
  • 再调用operator new来分配内存。operator newmalloc作了一层简单的封装,等效于malloc
  • 将指向operator new的返回值类型转换为此次分配对象_Tp的指针类型。

整个过程如下:

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

#if __cpp_aligned_new
      if (alignof(_Tp) > __STDCPP_DEFAULT_NEW_ALIGNMENT__)
      {
   
        std::align_val_t __al = std::align_val_t(alignof(_Tp));
        return static_cast<_Tp *>(::operator new(__n * sizeof(_Tp), __al));
      }
#endif
      return static_cast<_Tp *>(::operator new(__n * sizeof(_Tp)));
    }
deallocate

deallocate函数,

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值