个人学习-STL深入学习01-vectory源码研习 // 需要补充
参考资料:
[1]博主:一枚程序员 STL源码剖析--vector https://www.cnblogs.com/sooner/p/3273395.html
[2]博主:劲蜡鸡腿堡 vector源码分析 https://blog.csdn.net/qq_37654704/article/details/108005334
[3]up主:双笙子佯谬 【C++公开课】全面理解STL标准库 vector容器 https://www.bilibili.com/video/BV1qF411T7sd/?spm_id_from=333.788&vd_source=1aa8abe26fd29751475807b1e7adcd89
[4]STL源码分析[M] 侯捷著
STL简述
STL,即标准模板库(Standard Template Library,STL),内部封装了常见的容器和算法。
由六部分组成:1.容器(Containers)2.分配器(Allocators)3.算法(Algorithm) 4.迭代器(Iterators) 5.适配器(Adapters) 6.仿函数(Functors)
容器通过分配器获取内存空间,算法通过迭代器获取容器内容,仿函数协助算法完成策略变化,适配器可以修改仿函数;
实现了数据结构和算法的分离,是C++模版编程和C++面向对象的最佳实践之一;
本系列希望通过对源码的学习,加深对C++模版编程的理解,精进编程思想;
vector简述
vector本身是连续型数据结构,类似于C语言中标准数组。
标准数组在分配空间后,想要进行扩展,需要如下步骤
1.新分配内存空间
2.把原数组拷贝至新空间;
3.释放原空间;
而vector的动态扩容,实际也是通过对这些行为进行封装,类内自动进行内存管理;
Vector的容量(capacity)和大小(size)
声明vector类,用sizeof查看大小,可得到vectory的大小,24(64位机的大小,不受数组内元素的影响),由三个指针构成
pointer __begin_;
pointer __end_;
__compressed_pair<pointer, allocator_type> __end_cap_;
和数组类似,verctory实际是一个在内存中连续分配的内存空间;(在堆中,由alloc分配)
begin,指向数组0号元素地址;
end;指向数组最后一个元素的下一个地址;
end_cap;表示数组声明后,分配空间的终点内存地址;
begin到end,表示已经初始化的内存空间;
end到capacity,属于vectory,但是没有初始化的内存空间;
end - begin = size, 容器内容的数据大小;
end_cap - begin = capacity, 分配的内存大小,可以存储的数据量的多少;
vectory自动扩容的函数和实现
vectory最大的特点是可以动态分配内存,涉及动态分配的函数有这些:
构造函数,操作符=,push_back(),shrink_to_fit(),insert()
构造函数:
待补充;
push_back()
源码
template <class _Allocator>
void
vector<bool, _Allocator>::push_back(const value_type& __x)
{
// _size = capacity时进行扩容;
if (this->__size_ == this->capacity())
reserve(__recommend(this->__size_ + 1));
++this->__size_;
back() = __x;
}
// 自动扩容
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));
}
简单解析:
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));
insert
源码
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;
}
插入时,校验是否size < capacity, true, 使用迭代器插入元素;
否则使用reserve+recommend进行扩容;
vectory管理的函数(简述):
resize();
设置元素数目,少的填充,实际就是初始化;
clear();
调用vectory中所有成员的析构函数,但是不会是否capacity,不会真正释放内存
reserve();
更改内存容量函数,动态扩容通过本函数完成
shrink_to_fit()
释放capacity > size的部分
erase()
移除指定位置的元素;
个人学习-STL深入学习01-vectory源码研习 // 需要补充的更多相关文章
- JDK1.8源码分析01之学习建议(可以延伸其他源码学习)
序言:目前有个计划就是准备看一下源码,来提升自己的技术实力.同时现在好多面试官都喜欢问源码,问你是否读过JDK源码等等? 针对如何阅读源码,也请教了我的老师.下面就先来看看老师的回答,也许会有帮助呢. ...
- 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试
机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...
- 深度学习(七十一)darknet 源码阅读
深度学习(七十一)darknet 源码阅读
- Spring Cloud 学习 之 Spring Cloud Eureka(源码分析)
Spring Cloud 学习 之 Spring Cloud Eureka(源码分析) Spring Boot版本:2.1.4.RELEASE Spring Cloud版本:Greenwich.SR1 ...
- Java并发包源码学习系列:线程池ScheduledThreadPoolExecutor源码解析
目录 ScheduledThreadPoolExecutor概述 类图结构 ScheduledExecutorService ScheduledFutureTask FutureTask schedu ...
- Netty 学习(十):ChannelPipeline源码说明
Netty 学习(十):ChannelPipeline源码说明 作者: Grey 原文地址: 博客园:Netty 学习(十):ChannelPipeline源码说明 CSDN:Netty 学习(十): ...
- 线程池底层原理详解与源码分析(补充部分---ScheduledThreadPoolExecutor类分析)
[1]前言 本篇幅是对 线程池底层原理详解与源码分析 的补充,默认你已经看完了上一篇对ThreadPoolExecutor类有了足够的了解. [2]ScheduledThreadPoolExecut ...
- (转)Android学习进阶路线导航线路(Android源码分享)
转载请注明出处:http://blog.csdn.net/qinjuning 前言:公司最近来了很多应届实习生,看着他们充满信心但略带稚气的脸庞上,想到了去年的自己,那是的我是不是也和 现在的他们一 ...
- Hadoop-1.2.1学习之Job创建和提交源码分析
在Hadoop中,MapReduce的Java作业通常由编写Mapper和Reducer開始.接着创建Job对象.然后使用该对象的set方法设置Mapper和Reducer以及诸如输入输出等參数,最后 ...
随机推荐
- 关于加密通道规范,你真正用的是TLS,而非SSL
摘要:事实上我们现在用的都是TLS,但因为历史上习惯了SSL这个称呼,平常还是以SSL为多. 本文分享自华为云社区<SSL和TLS的联系及区别>,作者: HZDX. TLS/SSL是一种加 ...
- Kube-OVN v1.10.0:新增Windows节点支持,用户自定义子网ACL等10+硬核功能
在Kube-OVN社区小伙伴的共同努力下,Kube-OVN v1.10.0于五月份正式发布.Kube-OVN v1.10.0版本中,我们一如既往地对Kube-OVN 的功能.性能.稳定性和易用性进行了 ...
- MyCat应用实战
下载Mycat https://github.com/MyCATApache/Mycat-Server/releases Mycat基础分库 基础配置 修改server.xml <user na ...
- JDK1.7HashMap源码分析
1.1首先HashMap中的Hash(哈希)是什么? Hash也称散列,哈希,对应的英文都是Hash.基本原理就是把任意长度的输入通过Hash算法变成固定长度的输出,这个映射的规则就是对应的Ha ...
- 《HALCON数字图像处理》第三章笔记
目录 第三章 HALCON图像处理基础 HALCON控制语句 HALCON算子 HALCON图像处理入门 HALCON图像读取 HALCON图像显示 图形窗口 图像显示 显示文字 HALCON图像转换 ...
- ElasticSearch7.3学习(三十一)----Logstash基础学习
一.Logstash基本介绍 Logstash 是一个功能强大的工具,可与各种部署集成. 它提供了大量插件,可帮助你解析,丰富,转换和缓冲来自各种来源的数据(文件.数据库......).logstas ...
- flowable与camunda性能测试对比分析
前言 目前主流的Java开源流程引擎有Activiti.Flowable.Camunda,笔者在进行流程引擎技术选型时,除了功能方面,性能和稳定性是尤其关注的指标,是选择Flowable?还是Camu ...
- 为什么 C# 访问 null 字段会抛异常?
一:背景 1. 一个有趣的话题 最近在看 硬件异常 相关知识,发现一个有意思的空引用异常问题,拿出来和大家分享一下,为了方便讲述,先上一段有问题的代码. namespace ConsoleApp2 { ...
- NC15553 数学考试
NC15553 数学考试 题目 题目描述 今天qwb要参加一个数学考试,这套试卷一共有 \(n\) 道题,每道题qwb能获得的分数为 \(a_i\) ,qwb并不打算把这些题全做完, 他想选总共 \( ...
- Tapdata Cloud 版本上新!新增ClickHouse,ADB MySQL等5个数据源支持
Tapdata Cloud cloud.tapdata.net Tapdata Cloud 是国内首家异构数据库实时同步云平台,目前支持Oracle.MySQL.PG.SQL Server.Mongo ...