当前位置: 首页 > news >正文

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就认为该位置迭代器失效了。

http://www.jsqmd.com/news/340054/

相关文章:

  • 全网最强汉字游戏:汉字加一笔耶
  • YOLO26最新创新改进系列:叫叫兽原创二次创新!上下文+CBAM捕捉中远距离像素间的语义关联,将全局场景信息有效融合到局部特征中,为YOLO26提供了原本缺失的“大局观”,有效涨点,嘎嘎创新!!!!
  • 【工具】基于Cloudflare的导师评价网
  • 标准漏孔生产厂家/气密检测设备哪家好?2026年优质标准漏孔生产厂家大盘点!气密检漏仪优选汇总 - 栗子测评
  • 2026杭州免费咨询律所推荐+杭州律师事务所推荐+杭州本地律所推荐杭州企业法律顾问哪家好合集! - 栗子测评
  • 2026年比较好的龙凤无人机/龙凤呈祥无人机厂家口碑推荐汇总 - 行业平台推荐
  • 2026年口碑好的陕西有机水溶肥用户好评厂家推荐 - 行业平台推荐
  • 在单片机串口接收程序中,通常每接收完一条报文就添加一条接收时间,而不是每接收一个字节。这是因为报文是逻辑单元,添加时间戳到完整报文更合理和高效。
  • 电脑端串口助手一个时间戳后面跟几条完整报文,而不是每条报文添加一个时间戳,这是依据什么确定添加接收时间戳
  • 还要多久?NASA卫星从太空俯瞰,那条通往“正义”的道路
  • 什么是住宅代理IP?
  • 使用 Depth Anything V2 进行单目深度估计
  • 设计模式 -详解
  • 2026年2月密集母线槽顶尖制造厂商深度评测与推荐 - 2026年企业推荐榜
  • 2026年靠谱的天然生物刺激素用户好评厂家推荐 - 行业平台推荐
  • 超1400个 MongoDB 数据库遭勒索
  • 2026年四川照明路灯供货商综合评测与选型指南 - 2026年企业推荐榜
  • 去哪儿网白盒漏洞 AI 运营实践
  • 2026年口碑好的陕西生物刺激素/陕西天然生物刺激素厂家专业度参考(精选) - 行业平台推荐
  • 2026年2月络合铁脱硫信誉供应商综合评选与选型指南 - 2026年企业推荐榜
  • 智能储物柜定制厂家+智能储物柜源头工厂,2026专业快递柜生产厂家优选盘点 - 栗子测评
  • 武汉高端眼镜店深度评测:如何甄选专业服务商 - 2026年企业推荐榜
  • Ps:清晰度和去除薄雾
  • 2026年口碑好的咖啡机/全自动咖啡机行业内口碑厂家推荐 - 行业平台推荐
  • 一文吃透 JavaScript 模块化:从 IIFE 到 ESM 的演进与实战
  • PPT配图神器01Agent:3秒生成可编辑配图,AI帮你告别找图烦恼
  • 港科校友|李铭鸿,李泓曦:一脉相承
  • libtorch_cpu.so: undefined symbol: iJIT_NotifyEvent解决方法
  • 万象生鲜B端配送系统——复刻美菜/快驴模式,赋能餐饮供应链高效升级
  • HSPF水文水质模型技术应用——原理、前后处理、参数率定、水质泥沙模拟、高级耦合