vector函数_C++ vector成员函数实现-alloc相关

1e22e96128a9365b49b9e880e757029c.png

本篇是为了帮助理解这篇:

No.9:C++ vector成员函数实现[持续更新]​zhuanlan.zhihu.com
c26e4450bdae8631bd30373310472259.png

内存分配相关的内容,而又防止太琐碎,所以单独开的,也是一篇学习笔记。其中有几块内容是比较困惑的,展开学习一下。

这块有点背景要讲,比较绕,尽量说清楚,多想几遍

在<stl_vector>中,如下代码片段,其中_Alloc=std::allocator<_Tp>,并且在_Vector_impl中封装了__alloc_traits的allocate和deallocate函数,用于分配释放内存

嵌套了两层

      typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
        rebind<_Tp>::other _Tp_alloc_type;
      typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer
       	pointer;

      struct _Vector_impl 
      : public _Tp_alloc_type

因此首先看下__alloc_traits


[1] __alloc_traits

__alloc_traits在ext/alloc_traits中定义,类继承自std::allocator_traits

/**
 * @brief  Uniform interface to C++98 and C++11 allocators.
 * @ingroup allocators
*/
template<typename _Alloc>
  struct __alloc_traits
#if __cplusplus >= 201103L
  : std::allocator_traits<_Alloc>
#endif
  • 其中的静态成员::template rebind<_Tp>::other在154-156行,如下
    template<typename _Tp>
      struct rebind
      { typedef typename _Alloc::template rebind<_Tp>::other other; };

可见,实际是_Alloc::template rebind<_Tp>::other,(在下面知就是allocator<_Tp1>)

  • 成员函数
    static pointer
    allocate(_Alloc& __a, size_type __n)
    { return __a.allocate(__n); }

    static void deallocate(_Alloc& __a, pointer __p, size_type __n)
    { __a.deallocate(__p, __n); }

实际上是用第一个参数作为函数来调用,而其中的_Alloc就是下面[2]介绍的,所以要看下这个变量的三个同名函数的实现


[2]std::allocator<_Tp>其中_Tp为内置或自定义类型

其中的泛型,具体化为std::allocator<_Tp>时,研究下一些具体的实现策略

定义在<bits/allocator>中

  • 66行-97行allocator具体化
  • 100行-142行allocator继承自__allocator_base

定义在25行-55行,是new_allocator的类型别名,下面[4]中探究

/** @file bits/c++allocator.h
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{memory}
 */

#ifndef _GLIBCXX_CXX_ALLOCATOR_H
#define _GLIBCXX_CXX_ALLOCATOR_H 1

#include <ext/new_allocator.h>

#if __cplusplus >= 201103L
namespace std
{
  /**
   *  @brief  An alias to the base class for std::allocator.
   *  @ingroup allocators
   *
   *  Used to set the std::allocator base class to
   *  __gnu_cxx::new_allocator.
   *
   *  @tparam  _Tp  Type of allocated object.
    */
  template<typename _Tp>
    using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
}
#else
// Define new_allocator as the base class to std::allocator.
# define __allocator_base  __gnu_cxx::new_allocator
#endif
  • 144行-166行重载一些运算符
  • rebind在119行-121行
      template<typename _Tp1>
        struct rebind
        { typedef allocator<_Tp1> other; };

[3]allocator_traits<_Alloc>的实现

这个变量可以定位到<bits/alloc_traits>,下面都是围绕这个头文件说明源码

45行到76行都是结构体__allocator_traits_base的定义

82行到360行是结构体allocator_traits的定义

363行到486行是结构体allocator_traits的部分具体化

这个没什么实质内容

[4]new_allocator探究

截取下面这段函数研究下

      pointer
      address(reference __x) const _GLIBCXX_NOEXCEPT
      { return std::__addressof(__x); }

      const_pointer
      address(const_reference __x) const _GLIBCXX_NOEXCEPT
      { return std::__addressof(__x); }

      // NB: __n is permitted to be 0.  The C++ standard says nothing
      // about what the return value is when __n == 0.
      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)));
      }

      // __p is not permitted to be a null pointer.
      void
      deallocate(pointer __p, size_type)
      { ::operator delete(__p); }

      size_type
      max_size() const _GLIBCXX_USE_NOEXCEPT
      { return size_t(-1) / sizeof(_Tp); }

可见分配内存最后还是用::operatornew

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值