STL源码剖析-vector
STL(Standard Template Library)
我们使用库函数非常方便,且非常高效(相对于自己实现来说)。那如此好用的模板库它的内里是什么样的?它背着我们施展了什么“魔法”呢?我决定一探究竟,相信你也是一样。我会选用部分重要代码做分析,用来提升自己,希望后来的你在我的拙见中也能有自己的收获。
vector
数据存储方式:线性存储(一块连续内存),类似array。
相比于内置数组(不是array哦)的优势:动态扩容。(其实也不算什么优势,数组也完全可以做,只不过它把扩容过程高效安全地封装了起来。)
相比于array,优势就更大了,array的容量开始就是定死了的,无法扩容。
使用方法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; // unique_ptr::get vs unique_ptr::release
int main()
{
//初始化
vector<int> vec;//声明,未初始化
vector<int> vec1(, );//2个5
vector<int> vec2 = { , , , , };//直接初始化
//读取元素
cout << "第2个元素: " << vec2[] << endl;
cout << "首元素: " << vec2.front() << endl;
cout << "尾元素: " << vec2.back() << endl;
//插入元素
vec1.insert(vec1.begin(), );//para1-插入位置,要迭代器即指针,para2-插入内容
vec2.push_back();//尾部插入
vec2.pop_back();//删除尾部,类似于stack,所以有时候也可以把vector当stack用
//删除元素
vec2.erase(vec2.end()-);//参数也是迭代器类型,所以使用insert和erase时,最好用iterator来遍历
//排序
sort(vec2.begin(), vec2.end());//给出首位指针
sort(vec2.begin(), vec2.begin()+);//甚至这样也可以,因为iterator本身就是类型指针 //遍历--下标索引访问
cout << "vec1 : " ;
for (int i = ; i < vec1.size(); ++i)
{
cout << vec1[i] << " ";
} //遍历--迭代器指针访问
cout << "\nvec2 : ";
vector<int>::iterator it;
for (it=vec2.begin(); it != vec2.end(); ++it)
{
cout << *it << " ";
}
41 //使用指针遍历vector
auto vec = new vector<int>(10, 8);
for(int i=0; i<vec->size(); i++)
cout << (*vec)[i] << " ";
return ;
}
好了,基本的用法就是这样。
底层是怎么实现的呢?
在STL源码中,vector类维护有三个迭代器(三个类型指针)start, finish, end_of_storage, 分别代表头, 尾(实际使用的), vector 存储尾部(占用的,通常大于实际使用)。

当我们vector<TYPE>::iterator it;时,it就是TYPE* 类型指针,上述三个迭代器也是如此。
库函数的实现呢?


我们可以看出,通过上述的三个指针,几乎所有的操作都可以进行了。值得一提的是vector重载了[ ],可以方便存取值。
需要注意的是,当我们访问尾元素时,迭代器可不是*.end(),而是*.end()-1。
那么我们再来探讨一下,有意思的东西。
插入元素时,预设的end_of_storage不够怎么办?怎么进行扩容。

再看源码!


整个的流程是:
1.先申请两倍内存,判断够不够,够进入2;否则,分配需要的大小;
2.拷贝要插入点之前的内容
3.构造插入元素顺次添加到后面
4.接着把之前插入点后面的内容拷贝到新的空间中
5.释放原来空间

来看一下GCC的vector扩容过程,大概是,不够就扩充为原来2倍,扩充为原来2倍还不够,则扩充至需要大小。
int main()
{
vector<int> vec;
for(int i=; i<; i++)
{
cout << "vector size= " << vec.size() << endl;
cout << "vector capacity= " << vec.capacity() << endl;
//cout << "vector max_size= " << vec.max_size() << endl;
vec.push_back(i);
}
cout << "最后一次, 插入100个元素 " << endl;
vec.insert(vec.begin(), , );
cout << "vector size= " << vec.size() << endl;
cout << "vector capacity= " << vec.capacity() << endl;
//cout << "vector max_size= " << vec.max_size() << endl; return ;
}

但是,vector最大空间是固定的。
我用同一段代码测试vector的最大空间 ,这里有一个疑问,要是超过额定最大空间又会怎么样?最后有尝试。
int main()
{
vector<int> vec;
for(int i=; i<; i++)
{
cout << "Max_size = " << vec.max_size() << endl;
cout << "size = " << vec.size() << endl;
vec.push_back(i);
cout << "插入 " << i << endl;
}
return ;
}
(1)GCC 1019

(2)MSVC 109

超出上述max_size后,被系统拒绝insert了,我想那是它的极限了,不能突破。
至此,我们对STL vector的实现就差不多了解了,出去侃侃也足够了。
代码来自《STL源码解析》,源码迸发着光辉!
STL源码剖析-vector的更多相关文章
- STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...
- STL"源码"剖析-重点知识总结
STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...
- 【转载】STL"源码"剖析-重点知识总结
原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...
- STL源码剖析 迭代器(iterator)概念与编程技法(三)
1 STL迭代器原理 1.1 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...
- STL"源码"剖析
STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...
- 《STL源码剖析》相关面试题总结
原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...
- STL源码剖析之序列式容器
最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ...
- STL源码剖析 — 空间配置器(allocator)
前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配 ...
- c++ stl源码剖析学习笔记(一)uninitialized_copy()函数
template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy ...
随机推荐
- 软件测试自动化的最新趋势对开源测试管理软件ITEST的启示
https://www.infoq.cn/article/c-LHJS2ksuDxp1WkrGl4 理面提到几点,DevOps 的关键原则是开发团队.测试团队和运营团队协作,无缝发布软件.这意味着集中 ...
- NumPy 超详细教程(1):NumPy 数组
系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 文章目录 Numpy 数组:n ...
- Java3y文章目录导航
由于写的文章已经是有点多了,为了自己和大家的检索方便,于是我就做了这么一个博客导航. 想要获取最新原创的技术文章欢迎关注我的公众号:Java3y 文章目录导航:https://github.com/Z ...
- HTML 练习实现鼠标移到用户图像展示更多信息
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Challenges-XSS
https://alf.nu/alert1 warmup adobe JSON
- Windows Server 2016-MS服务器应用程序兼容性列表
该表罗列支持 Window Server 2016 上安装和功能的 Microsoft 服务器应用程序. 此信息用于快速参考,不用于替代有关单个产品的规格.要求.公告或每个服务器应用程序的常规通信的说 ...
- Visual Studio Code快速删除空行及几个常用快捷键总结
在使用notepad++工具的时候,很多情况下我们会遇到批量替换空行的操作,之前的操作方法是快捷键Crtl+h调出窗口选择替换栏,在查找目标栏中输入\r\n\r\n,替换为 栏中输入\r\n并选择全部 ...
- Windows下建立FTP服务器站点
环境 操作系统版本:Win7旗舰版64位系统 1.安装FTP组件 打开或关闭Windows功能,打开过程可能会比较慢,大概3.4分钟: 安装FTP组件.勾选Internet信息服务下的FTP服务器.F ...
- Storm入门(十)Twitter Storm: Transactional Topolgoy简介
作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/736/twitter-stor ...
- Luogu P5279 [ZJOI2019]麻将
ZJOI2019神题,间接送我退役的神题233 考场上由于T2写挂去写爆搜的时候已经没多少时间了,所以就写挂了233 这里不多废话直接开始讲正解吧,我们把算法分成两部分 1.建一个"胡牌自动 ...