news 2026/5/14 21:21:36

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/5/11 9:20:31

港科校友|李铭鸿,李泓曦:一脉相承

以信任和爱作为家庭的基石&#xff0c;校友李铭鸿Thomas和儿子李泓曦Conan先后踏上科大的教育之路&#xff0c;体现了大学一直培养的探索精神与独特个性。Conan全心投入本科学习&#xff0c;而父母灌输给他的自由、幸福和相互尊重的价值观继续引导着他&#xff0c;展示了科大一…

作者头像 李华
网站建设 2026/5/3 5:58:28

ava面试速成版,背这份八股文(含答案)就对了!

别再拿旧资料瞎准备了&#xff01;看看我们这份联合2025-2026届成功入职头部企业的12位准大厂人&#xff0c;深挖近3个月一线互联网、科技公司的真实面经反馈、核心考察重点&#xff0c;把大厂面试官的提问逻辑、评分标准、高频考点全拆解&#xff0c;耗时打磨出这份「最新大厂…

作者头像 李华
网站建设 2026/5/10 2:23:32

NAS的大内存有必要吗?到底需不需要 SSD 缓存?核心逻辑一次讲清

NAS的大内存有必要吗&#xff1f;到底需不需要 SSD 缓存&#xff1f;核心逻辑一次讲清 哈喽小伙伴们好&#xff0c;我是Stark-C~ 前段时间有个粉丝在我的推荐下入手了极空间Z4Pro &#xff0c;当时的好价仅需两千出头&#xff0c;确实挺划算的&#xff0c;只不过到手的是8GB内…

作者头像 李华
网站建设 2026/5/13 14:04:27

橙色工作汇报PPT模板

扫描下载文档详情页: https://www.didaidea.com/wenku/16415.html

作者头像 李华
网站建设 2026/5/14 4:14:03

本地搭建 Clawdbot + ZeroNews 访问

最近&#xff0c;一个名为 ClawdBot&#xff08;现已更名 OpenClaw&#xff09; 的项目在技术圈引起了广泛讨论。许多人称其为“真正能做实事的 AI”、“个人 AI 助理的未来形态”。它不仅仅是一个聊天机器人&#xff0c;更是一个能够接入日常工作、生活&#xff0c;直接在用户…

作者头像 李华
网站建设 2026/5/12 12:13:17

告别建站难 + 访问限!Halo+cpolar 让个人博客从局域网飞向全网

Halo 是一款轻量化的开源建站工具&#xff0c;核心功能围绕个人博客搭建展开&#xff0c;支持文章编辑、主题切换、插件拓展等基础且实用的建站需求&#xff0c;适配 Windows、Linux、macOS 多系统&#xff0c;操作界面简洁易懂&#xff0c;既适合零基础的学生、内容创作者快速…

作者头像 李华