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

【C++/STL】vector基本介绍

vector的介绍及使用

介绍
1.vector表示可变大小数组的序列容器。
2.vector像数组一样采用连续的存储空间来存储数据,意味着可以采用下标对vector的元素进行访问。它的大小可以动态改变且会被容器自动处理。
3.vector的底层实现采用动态分配数组内存来存储它的元素。当新元素插入时,可能需要重新分配并增加存储空间。做法为:分配一个新的数组,然后将全部元素移到这个数组中,时间开销较大,所以当容器中添加新元素时,vector并不会每次都重新分配大小。
4.分配策略为:vector会额外分配一些空间以适应可能的增长。不同的库采用不同的策略来权衡空间的使用和重新分配。
5.与其他容器相比,vector在访问元素时更高效,在末尾删除或添加元素时更高效。
使用
vector的文档介绍
以下是需要重点掌握的接口:

vector的定义

1.vector()      无参构造
2.vector(size_type n, const value_type& val = value_type()) 构造并初始化n个val
3. vector(const vector& x)   拷贝构造
4. vector(InputIterator first,InputIterator last)  使用迭代器进行初始化构造

vector iterator的使用
1.begin+end
获取第一个数据位置或最后一个数据的下一个位置iterator/const_iterator
(迭代器区间为左闭右开)
2.rbegin+rend
获取最后一个数据位置或第一个数据的前一个位置reverset_iterator
在这里插入图片描述
vector空间增长问题
在这里插入图片描述
resize reserve

vs下capacity是按1.5倍增长的,g++是按2倍增长的。vs是PJ版本STL,g++是SGI版本STL。reserve只负责开辟空间,确定知道要用多少空间时更高效。resize在开空间的同时会进行初始化,影响size。
//在两种环境下测试vector的默认扩容机制
在这里插入图片描述
在这里插入图片描述
若已知大概空间大小,用reserve提高效率
在这里插入图片描述
vector增删查改

在这里插入图片描述

vector迭代器失效问题(重难点)

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

在这里插入图片描述
vector可能会导致其迭代器失效的操作有:
1.会引起其底层空间改变的操作(如扩容),都有可能是迭代器失效,比如:resize、reserve、insert、assign、push_back等.

int main()
{vector<int> v{ 2,4,6,8,9,5 };vector<int>::iterator it = v.begin();v.resize(100, 6);v.reserve(150);v.insert(v.begin(), 0);v.push_back(8);v.assign(100, 7);return 0;
}

扩容会使旧空间被释放掉,而在打印时,it还使用的是释放之间的旧空间,在对it迭代器操作时,实际操作的是一块已经被释放的空间,而引起代码运行时崩溃。
解决方式:在以上操作完成之后,如果想要继续通过迭代器操作vector中的元素,只需给it重新
赋值即可。

2.指定位置元素的删除操作–erase
在这里插入图片描述
erase删除pos位置元素后,pos位置之后的元素会往前搬移,没有导致底层空间的改变,理论上讲迭代器不应该会失效,但是:如果pos刚好是最后一个元素,删完之后pos刚好是end的位置,而end位置是没有元素的,那么pos就失效了。因此删除vector中任意位置上元素时,vs就认为该位置迭代器失效了。
3. Linux下,g++编译器对迭代器失效的检测并不是非常严格,处理也没有vs下极端。
比如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上程序可正常运行:
在这里插入图片描述
erase删除的迭代器如果是最后一个元素,删除之后it已经超过end,此时迭代器是无效的,++it导致程序崩溃。
从上述例子中可以看到:SGI STL中,迭代器失效后,代码并不一定会崩溃,但是运行结果肯定不
对,如果it不在begin和end范围内,一定会崩溃。
4. 与vector类似,string在插入+扩容操作+erase之后,迭代器也会失效。

#include <string>
void TestString() 
{string s("hello");auto it = s.begin();// 放开之后代码会崩溃,因为resize到20会string会进行扩容// 扩容之后,it指向之前旧空间已经被释放了,该迭代器就失效了// 后序打印时,再访问it指向的空间程序就会崩溃//s.resize(20, '!');while (it != s.end()){cout << *it;++it;}cout << endl;it = s.begin();while (it != s.end()){it = s.erase(it);// 按照下面方式写,运行时程序会崩溃,因为erase(it)之后// it位置的迭代器就失效了// s.erase(it); //++it;}
}

erase会自动返回下一个有效迭代器。
迭代器失效解决办法:在使用前,对迭代器重新赋值。

http://www.dtcms.com/a/310007.html

相关文章:

  • 关于cherryusb的in/out完成条件
  • WAIC现场速递:AI热浪扑面而来|小奇说
  • QD9361开发板教程:基于zynq的PS端的DDR3测试
  • Vue+Cesium 基础搭建
  • 智能体的未来:AGI路径上的关键技术突破
  • 分类预测 | Matlab实现CPO-PNN冠豪猪算法优化概率神经网络多特征分类预测
  • Win11怎样安装DirectX 9
  • 稳健标准误
  • 【苍穹外卖项目】Day05
  • draw_ctx中clip_area和buf_area的区别,为什么看起来差不多?
  • 第四篇:材质与纹理:让物体“真实“起来
  • Linux选择
  • evo_traj的参数设置及保存图片
  • van list 重复进入onload
  • c++和python联合编程示例
  • Conda install安装了一些库,如何撤销操作
  • 《n8n基础教学》第一节:如何使用编辑器UI界面
  • Day17--二叉树--654. 最大二叉树,617. 合并二叉树,700. 二叉搜索树中的搜索,98. 验证二叉搜索树
  • chroma、faiss和milvus三者之间的区别和联系
  • 数据结构——查找(一、什么是查找?)
  • 通过观看数百个外科手术视频课程来学习多模态表征|文献速递-医学影像算法文献分享
  • OpenVLA: 论文阅读 -- 开源视觉-语言-行动模型
  • 我用提示词A 对qwen3-4b大模型进行 nl2sql 任务 grpo 强化学习,评估的时候换新提示词,会影响nl2sql测评准确率吗?
  • IOMMU Client设备DMA配置过程分析(九)
  • “物联网+技校”:VR虚拟仿真实训室的发展前景
  • ALOcc: Adaptive Lifting-based 3D Semantic Occupancy and
  • Python爬虫实战:研究pycares技术构建DNS解析系统
  • Web开发-PHP应用组件框架前端模版渲染三方插件富文本编辑器CVE审计
  • 从0到1学PHP(十四):PHP 性能优化:打造高效应用
  • 基于 USBD 库 CDC Standalone 例程中的一个 Bug 解析