个人学习-STL深入学习01-vectory源码研习 // 需要补充

STL,即标准模板库(Standard Template Library,STL),内部封装了常见的容器和算法。
由六部分组成:1.容器(Containers)2.分配器(Allocators)3.算法(Algorithm) 4.迭代器(Iterators) 5.适配器(Adapters) 6.仿函数(Functors)
容器通过分配器获取内存空间,算法通过迭代器获取容器内容,仿函数协助算法完成策略变化,适配器可以修改仿函数;
实现了数据结构和算法的分离,是C++模版编程和C++面向对象的最佳实践之一;
本系列希望通过对源码的学习,加深对C++模版编程的理解,精进编程思想;

vector本身是连续型数据结构,类似于C语言中标准数组。
标准数组在分配空间后,想要进行扩展,需要如下步骤
1.新分配内存空间
2.把原数组拷贝至新空间;
3.释放原空间;
而vector的动态扩容,实际也是通过对这些行为进行封装,类内自动进行内存管理;

声明vector类,用sizeof查看大小,可得到vectory的大小,24(64位机的大小,不受数组内元素的影响),由三个指针构成

    pointer                                         __begin_;
    pointer                                         __end_;
    __compressed_pair<pointer, allocator_type> __end_cap_;
</pointer,>

和数组类似,verctory实际是一个在内存中连续分配的内存空间;(在堆中,由alloc分配)
begin,指向数组0号元素地址;
end;指向数组最后一个元素的下一个地址;
end_cap;表示数组声明后,分配空间的终点内存地址;
begin到end,表示已经初始化的内存空间;
end到capacity,属于vectory,但是没有初始化的内存空间;
end – begin = size, 容器内容的数据大小;
end_cap – begin = capacity, 分配的内存大小,可以存储的数据量的多少;

vectory最大的特点是可以动态分配内存,涉及动态分配的函数有这些:
构造函数,操作符=,push_back(),shrink_to_fit(),insert()
构造函数:
待补充;

  template <class _allocator>
  void
  vector<bool, _allocator>::push_back(const value_type& __x)
  {
  // _size = capacity&#x65F6;&#x8FDB;&#x884C;&#x6269;&#x5BB9;;
      if (this->__size_ == this->capacity())
          reserve(__recommend(this->__size_ + 1));
      ++this->__size_;
      back() = __x;
  }
  // &#x81EA;&#x52A8;&#x6269;&#x5BB9;
  template <class _allocator>
  inline _LIBCPP_INLINE_VISIBILITY
  typename vector<bool, _allocator>::size_type
  vector<bool, _allocator>::__recommend(size_type __new_size) const
  {
      const size_type __ms = max_size();
      if (__new_size > __ms)
          this->__throw_length_error();
      const size_type __cap = capacity();
      if (__cap >= __ms / 2)
          return __ms;
      return _VSTD::max(2 * __cap, __align_it(__new_size));
  }
</bool,></bool,></class></bool,></class>

简单解析:
1.push_back(),当发现size() == capacity(),需要扩容,使用reserve函数重新对空间进行分配(reserve会在内存中开辟一片新空间,并把原容器进行拷贝);
2.分配大小为__recommend函数返回值;
缩小: if (__cap >= __ms / 2) return __ms; // size小于容量的一半,这个分支在push_back的时候不会调用;
扩大: max(2 * __cap, __align_it(__new_size));

template <class _allocator>
typename vector<bool, _allocator>::iterator
vector<bool, _allocator>::insert(const_iterator __position, const value_type& __x)
{
    iterator __r;
    if (size() < capacity())
    {
        const_iterator __old_end = end();
        ++__size_;
        _VSTD::copy_backward(__position, __old_end, end());
        __r = __const_iterator_cast(__position);
    }
    else
    {
        vector __v(__alloc());
        __v.reserve(__recommend(__size_ + 1));
        __v.__size_ = __size_ + 1;
        __r = _VSTD::copy(cbegin(), __position, __v.begin());
        _VSTD::copy_backward(__position, cend(), __v.end());
        swap(__v);
    }
    *__r = __x;
    return __r;
}
</bool,></bool,></class>

插入时,校验是否size < capacity, true, 使用迭代器插入元素;
否则使用reserve+recommend进行扩容;

设置元素数目,少的填充,实际就是初始化;

调用vectory中所有成员的析构函数,但是不会是否capacity,不会真正释放内存

更改内存容量函数,动态扩容通过本函数完成

释放capacity > size的部分

移除指定位置的元素;

Original: https://www.cnblogs.com/Albert-lihai/p/16576769.html
Author: Albert_禄遥
Title: 个人学习-STL深入学习01-vectory源码研习 // 需要补充

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/577716/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • vue-admin-template组件前端,登录验证成功后,getInfo方法不调用

    先查看request.js中自定义状态码是否为自己的定义的成功状态码 这里的状态码该为自己的成功状态码 Original: https://www.cnblogs.com/antl…

    Linux 2023年6月7日
    095
  • zabbix用户,角色,权限,模板管理

    zabbix用户,角色,权限,模板管理 用户组 用户角色 用户 使用刚才创建的用户登录 模板组 模板 模板的监控项可以自己创建也可以从其他模板复制 posted @2022-09-…

    Linux 2023年6月13日
    099
  • jdk8 线程池策略

    在ThreadPoolExecutor中提供了4种线程的策略可以供开发者直接使用:•AbortPolicy策略:默认策略,如果线程池队列满了丢掉这个任务并且抛出RejectedEx…

    Linux 2023年6月8日
    0109
  • JPA作持久层操作

    JPA(Hibernate是jpa的实现) jpa是对实体类操作,从而通过封装好的接口直接设置数据库的表结构。虽然jpa可以直接通过编写java代码来操作数据库表结构,避免了sql…

    Linux 2023年6月7日
    0114
  • MySQL的数据类型

    MySQL的数值类型 类型大小范围(有符号)范围(无符号)用途TINYINT 1 Bytes (-128,127)(0,255)小整数值SMALLINT 2 Bytes (-32 …

    Linux 2023年6月7日
    081
  • 【spring-boot】Redis的整合与使用详解

    在pom.xml中添加依赖 org.springframework.boot spring-boot-starter-data-redis 2.2.1.RELEASE io.let…

    Linux 2023年5月28日
    085
  • python异常处理

    关于异常 在程序运行中,总会遇到各种各样的错误,如打开一个不存在的文件,程序期待用户输入数字,但用户输入了字符串,网络传输终止等,如果不对这些可能引发异常的情况进行处理,就会导致抛…

    Linux 2023年6月7日
    0154
  • 爱前端公开课学习笔记——JS01 认识js 变量

    认识js 在谷歌浏览器的控制台中右键单击空白处,选择检查可以打开控制台 查看console.log输出的内容。 JS的注释 是”//”或者”/ …

    Linux 2023年6月14日
    090
  • 常用命令记录

    npm仓库查看和修改 npm config set registry https://registry.npm.taobao.org #设置使用淘宝提供的npm仓库 npm con…

    Linux 2023年6月14日
    064
  • 【转】我是一个CPU:这个世界慢!死!了!

    简介 经常听到有人说磁盘很慢、网络很卡,这都是站在人类的感知维度去表述的,比如拷贝一个文件到硬盘需要几分钟到几十分钟,够我去吃个饭啦;而从网络下载一部电影,有时候需要几个小时,我都…

    Linux 2023年6月16日
    0132
  • Linux系统编程—信号捕捉

    前面我们学习了信号产生的几种方式,而对于信号的处理有如下几种方式: 默认处理方式; 忽略; 捕捉。 信号的捕捉,说白了就是抓到一个信号后,执行我们指定的函数,或者执行我们指定的动作…

    Linux 2023年6月14日
    0112
  • 每天一个 HTTP 状态码 200

    200 OK 表示请求成功,一切安好… 200 OK 话不多说,这个状态码应该是最最最常用的了,无人不知,无人不晓;就是表示请求成功的意思, 你若安好,便是晴天。 摘自…

    Linux 2023年6月7日
    093
  • Redisson实现分布式锁源码解读

    文章目录 一、分布式锁的概念 和 使用场景 二、将redis官网对于分布式锁(红锁)的定义和Redisson实现做概括性总结 三、基于Redisson的分布式实现方案 四、加锁过程…

    Linux 2023年5月28日
    079
  • 更改网卡名称

    CentOS7使用了”一致性网络命名方法” 更改配置文件内容 关闭”一致性网络设备命名法” 更新GRUB、内核配置 grub2-mk…

    Linux 2023年6月6日
    079
  • 相关powerLink教程、配置方法等

    openPowerLink的开发小组早已经解散,所以有些资料都可以在官网上下载到; 这也是最后一次更新了。其中相关powerlink的教程均放在百度网盘里,链接:https://p…

    Linux 2023年6月14日
    098
  • MySQL里的那些日志们

    该系列博文会告诉你如何从入门到进阶,从sql基本的使用方法,从MySQL执行引擎再到索引、事务等知识,一步步地学习MySQL相关技术的实现原理,更好地了解如何基于这些知识来优化sq…

    Linux 2023年6月14日
    088
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球