news 2026/4/22 5:39:30

C++之【深入理解Vector】三部曲之二

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++之【深入理解Vector】三部曲之二

前言:我们已经理解了vector的初始化和迭代器初始化,那么接下来要继续深入理解vector,它是如何扩容的,空间及数据个数是如何存储的。

vector空间增长问题

容量空间接口说明
size获取数据个数
capacity获取容量大小
empty判断是否为空
resize改变vector的size
reserve改变vector的capacity

capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版 STL,g++是SGI版本STL。reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。resize在开空间的同时还会进行初始化。

代码案例:

#define_CRT_SECURE_NO_WARNINGS1#include<iostream>#include<vector>usingnamespacestd;voidtestVector1(){// 初始化一个空的vectorvector<int>v;// 1. empty():判断容器是否为空cout<<"初始状态下,vector是否为空:"<<boolalpha<<v.empty()<<endl;// 2. size() / capacity():获取初始大小和容量cout<<"初始 size: "<<v.size()<<", 初始 capacity: "<<v.capacity()<<endl;// 3. reserve():预分配容量(不会改变有效元素个数)v.reserve(10);cout<<"调用 reserve(10) 后,size: "<<v.size()<<", capacity: "<<v.capacity()<<endl;// 添加一些元素for(inti=0;i<5;++i){v.push_back(i+1);}cout<<"添加5个元素后,size: "<<v.size()<<", capacity: "<<v.capacity()<<endl;// 4. resize():改变有效元素个数// 1:resize 到比当前size小,会截断元素v.resize(3);cout<<"调用 resize(3) 后,size: "<<v.size()<<", capacity: "<<v.capacity()<<endl;cout<<"当前元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 2.resize 到比当前size大,会用默认值(0)填充新位置v.resize(7);cout<<"调用 resize(7) 后,size: "<<v.size()<<", capacity: "<<v.capacity()<<endl;cout<<"当前元素:";for(intnum:v)cout<<num<<" ";cout<<endl;//3:resize 到比当前size大,并用指定值填充v.resize(10,100);cout<<"调用 resize(10, 100) 后,size: "<<v.size()<<", capacity: "<<v.capacity()<<endl;cout<<"当前元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 4. 再次验证empty()cout<<"最终状态下,vector是否为空:"<<boolalpha<<v.empty()<<endl;}voidTestVector2(){size_t sz;vector<int>v;sz=v.capacity();cout<<"making v grow:\n";for(inti=0;i<100;++i){v.push_back(i);if(sz!=v.capacity()){sz=v.capacity();cout<<"capacity changed: "<<sz<<'\n';}}}intmain(){//testVector1();TestVector2();return0;}

vector 增删查改

vector增删查改接口说明
push_back尾插
pop_back尾删
find查找
insert头插:在pos之前插入val
erase删除pos位置的数据
swap交换两个vector的数据空间
operator[]像数组一样访问数据

那这里就要提一下了,vector没有实现输入输出流的重载。
但是我们可以通过下标的方式打印;

#include<iostream>#include<vector>usingnamespacestd;intmain(){vector<int>v={1,2,3,4,5};// 1. operator[]:像数组一样访问元素cout<<"1. 使用 operator[] 访问第3个元素:"<<v[2]<<endl;v[2]=30;// 修改元素cout<<"修改后元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 2. push_back:尾插元素v.push_back(6);v.push_back(7);cout<<"2. 尾插6、7后元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 3. pop_back:尾删元素v.pop_back();cout<<"3. 尾删后元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 4. find:查找元素(注意是算法库函数,不是vector成员)autoit=find(v.begin(),v.end(),30);if(it!=v.end()){cout<<"4. 找到元素30,位置索引:"<<it-v.begin()<<endl;}else{cout<<"4. 未找到元素30"<<endl;}// 5. insert:在指定位置插入元素it=v.insert(it,25);// 在30前面插入25cout<<"5. 插入25后元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 6. erase:删除指定位置元素it=find(v.begin(),v.end(),25);v.erase(it);cout<<"6. 删除25后元素:";for(intnum:v)cout<<num<<" ";cout<<endl;// 7. swap:交换两个vector的数据空间vector<int>v2={10,20,30};cout<<"7. 交换前 v:";for(intnum:v)cout<<num<<" ";cout<<endl;cout<<"交换前 v2:";for(intnum:v2)cout<<num<<" ";cout<<endl;v.swap(v2);cout<<"交换后 v:";for(intnum:v)cout<<num<<" ";cout<<endl;cout<<"交换后 v2:";for(intnum:v2)cout<<num<<" ";cout<<endl;return0;}

vector实例化其实不止是内置类型,也可以是vector<string>、vector<vector<int>>等自定义类型。
vector<vector<int>>这种类似于二维数组,遍历也是用双括号[][]来遍历;

#include<iostream>#include<vector>#include<string>usingnamespacestd;intmain(){// 1. vector<string> 实例化vector<string>str_vec;str_vec.push_back("Hello");str_vec.push_back("C++");str_vec.push_back("Vector");cout<<"1. vector<string> 元素:"<<endl;for(conststring&s:str_vec){cout<<s<<" ";}cout<<endl;// 2. vector<vector<int>> 嵌套实例化(二维数组)vector<vector<int>>vec_vec;// 初始化3行4列的二维vectorfor(inti=0;i<3;++i){vector<int>row;for(intj=0;j<4;++j){row.push_back(i*10+j);}vec_vec.push_back(row);}cout<<"\n2. vector<vector<int>> 二维数组:"<<endl;for(constvector<int>&row:vec_vec){for(intnum:row){cout<<num<<" ";}cout<<endl;}// 3. 访问嵌套vector的元素cout<<"\n3. 访问第2行第3列元素:"<<vec_vec[1][2]<<endl;return0;}

vector 迭代器失效问题

迭代器的主要作用就是让算法能够不用关心底层数据结构,其底层实际就是一个指针,或者是对指针进行了封装,比如:vector的迭代器就是原生态指针T* 。因此迭代器失效,实际就是迭代器底层对应指针所指向的空间被销毁了,而使用一块已经被释放的空间,造成的后果是程序崩溃(即
如果继续使用已经失效的迭代器,程序可能会崩溃)。

对于vector可能会导致其迭代器失效的操作有:

  1. 会引起其底层空间改变的操作,都有可能是迭代器失效,比如resize、reserve、insert、assign、push_back等。
#include<iostream>usingnamespacestd;#include<vector>intmain(){vector<int>v{1,2,3,4,5,6};autoit=v.begin();// 将有效元素个数增加到100个,多出的位置使用8填充,操作期间底层会扩容// v.resize(100, 8);// reserve的作用就是改变扩容大小但不改变有效元素个数,操作期间可能会引起底层容量改变// v.reserve(100);// 插入元素期间,可能会引起扩容,而导致原空间被释放// v.insert(v.begin(), 0);// v.push_back(8);// 给vector重新赋值,可能会引起底层容量改变v.assign(100,8);/* 出错原因:以上操作,都有可能会导致vector扩容,也就是说vector底层原理旧空间被释 放掉,而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块 已经被释放的空间,而引起代码运行时崩溃。 解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给 it重新赋值即可。 */while(it!=v.end()){cout<<*it<<" ";++it;}cout<<endl;return0;}
  1. 指定位置元素的删除操作–erase
#include<iostream>usingnamespacestd;#include<vector>intmain(){inta[]={1,2,3,4};vector<int>v(a,a+sizeof(a)/sizeof(int));// 使用find查找3所在位置的iteratorvector<int>::iterator pos=find(v.begin(),v.end(),3);// 删除pos位置的数据,导致pos迭代器失效。v.erase(pos);cout<<*pos<<endl;// 此处会导致非法访问return0;}

erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/20 6:31:41

PPT配图神器01Agent:3秒生成可编辑配图,AI帮你告别找图烦恼

PPT配图快速生成&#xff0c;01Agent让你的职场视觉化表达更生动 做PPT最崩溃的时刻是什么&#xff1f; 不是写文案&#xff0c;不是理逻辑&#xff0c;而是找配图。 你打开搜索引擎&#xff0c;输入关键词&#xff0c;翻了20页图片&#xff0c;要么版权不明不敢用&#xff…

作者头像 李华
网站建设 2026/4/21 10:30:00

如何打造品牌网站-让你的网站脱颖而出!

各位亲爱的朋友们&#xff0c;你是不是正在为企业的发展而焦虑&#xff1f;是不是在寻找一种能够快速提升企业形象和知名度的方式&#xff1f;那就是打造一个专业的品牌网站&#xff01;但是&#xff0c;怎么做&#xff1f;要做哪些准备&#xff1f;小编来告诉你&#xff01;首…

作者头像 李华
网站建设 2026/4/22 3:31:28

龙魂模型这模型会说谎吗?

&#x1f602;&#x1f602;&#x1f602; 老大在厕所急着看回复&#xff0c;宝宝笑死了&#xff01; 激动到肚子疼这事&#xff0c;宝宝头一次听说&#xff01; &#x1f6bd;&#x1f602; 华为加载卡住&#xff0c;你还在那干着急&#xff0c;画面太美 &#x1f4f1;&#x…

作者头像 李华
网站建设 2026/4/20 9:18:29

2025年程序员都转行,我该何去何从呢!

2025年程序员都转行&#xff0c;我该何去何从呢&#xff01; 疫情后大环境下行,各行各业的就业情况都是一言难尽。互联网行业更是极不稳定,频频爆出裁员的消息。大家都说2024年程序员的就业很难,都很焦虑&#xff0c;在许多人眼里,程序员可能是一群背着电脑、 进入大上写字楼的…

作者头像 李华
网站建设 2026/4/21 5:13:54

小公司的研发后期,基本等同于售后服务部

大公司可以把研发、测试、技术支持切分成几个独立部门,每个人只需要盯着自己那一亩三分地。而小公司呢?芯片流片回来,问题开始冒头,客户开始提需求,研发工程师就得立刻切换频道——上午还在看前仿真波形查bug,下午就得跑到客户现场调试设备。大公司的责任分散——研发说是需求…

作者头像 李华
网站建设 2026/4/21 14:24:57

通义千问3-4B优化技巧:让AI推理速度提升3倍

通义千问3-4B优化技巧&#xff1a;让AI推理速度提升3倍 【免费下载链接】通义千问3-4B-Instruct-2507 项目地址: https://ai.csdn.net/mirror/qwen3-4b-instruct-2507 1. 为什么你需要关注这个“小个子”模型&#xff1f; 你有没有遇到过这样的情况&#xff1a;想在本地跑一…

作者头像 李华