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的更多相关文章

  1. STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...

  2. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  3. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

  4. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

  5. STL"源码"剖析

    STL"源码"剖析-重点知识总结   STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...

  6. 《STL源码剖析》相关面试题总结

    原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...

  7. STL源码剖析之序列式容器

    最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ...

  8. STL源码剖析 — 空间配置器(allocator)

    前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配 ...

  9. c++ stl源码剖析学习笔记(一)uninitialized_copy()函数

    template <class InputIterator, class ForwardIterator>inline ForwardIterator uninitialized_copy ...

随机推荐

  1. 软件测试自动化的最新趋势对开源测试管理软件ITEST的启示

    https://www.infoq.cn/article/c-LHJS2ksuDxp1WkrGl4 理面提到几点,DevOps 的关键原则是开发团队.测试团队和运营团队协作,无缝发布软件.这意味着集中 ...

  2. NumPy 超详细教程(1):NumPy 数组

    系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 文章目录 Numpy 数组:n ...

  3. Java3y文章目录导航

    由于写的文章已经是有点多了,为了自己和大家的检索方便,于是我就做了这么一个博客导航. 想要获取最新原创的技术文章欢迎关注我的公众号:Java3y 文章目录导航:https://github.com/Z ...

  4. HTML 练习实现鼠标移到用户图像展示更多信息

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. Challenges-XSS

    https://alf.nu/alert1 warmup adobe JSON

  6. Windows Server 2016-MS服务器应用程序兼容性列表

    该表罗列支持 Window Server 2016 上安装和功能的 Microsoft 服务器应用程序. 此信息用于快速参考,不用于替代有关单个产品的规格.要求.公告或每个服务器应用程序的常规通信的说 ...

  7. Visual Studio Code快速删除空行及几个常用快捷键总结

    在使用notepad++工具的时候,很多情况下我们会遇到批量替换空行的操作,之前的操作方法是快捷键Crtl+h调出窗口选择替换栏,在查找目标栏中输入\r\n\r\n,替换为 栏中输入\r\n并选择全部 ...

  8. Windows下建立FTP服务器站点

    环境 操作系统版本:Win7旗舰版64位系统 1.安装FTP组件 打开或关闭Windows功能,打开过程可能会比较慢,大概3.4分钟: 安装FTP组件.勾选Internet信息服务下的FTP服务器.F ...

  9. Storm入门(十)Twitter Storm: Transactional Topolgoy简介

    作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://xumingming.sinaapp.com/736/twitter-stor ...

  10. Luogu P5279 [ZJOI2019]麻将

    ZJOI2019神题,间接送我退役的神题233 考场上由于T2写挂去写爆搜的时候已经没多少时间了,所以就写挂了233 这里不多废话直接开始讲正解吧,我们把算法分成两部分 1.建一个"胡牌自动 ...