当前位置: 首页 > 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.lryc.cn/news/607216.html

相关文章:

  • git pull和git fetch的区别
  • Linux---编辑器vim
  • vi/vim跳转到指定行命令
  • 达梦数据库权限体系详解:系统权限与对象权限
  • Js引用数据类型和ES6新特性
  • X2Doris是SelectDB可视化数据迁移工具,安装与部署使用手册,轻松进行大数据迁移
  • 向量投影计算,举例说明
  • rhcsa笔记大全
  • 华锐矩阵世界平台与海外客户洽谈合作
  • 网络协议之路由是怎么回事?
  • [buuctf-misc]百里挑一
  • 雷达微多普勒特征代表运动中“事物”的运动部件。
  • SD-WAN在煤矿机械设备工厂智能化转型中的应用与网络架构优化
  • Apache Flink 2.1.0: 面向实时 Data + AI 全面升级,开启智能流处理新纪元
  • forceStop流程会把对应进程的pendingIntent给cancel掉
  • C++ --- stack和queue的使用以及简单实现
  • 【AI问答】PromQL中interval和rate_interval的区别以及Grafana面板的配置建议
  • UE5 动态扫描波
  • python入门第一天---变量+数据类型及注释的使用
  • SpringAI智能客服Function Calling兼容性问题解决方案
  • LRU缓存淘汰算法的详细介绍与具体实现
  • 简单打包应用
  • pve 删除集群
  • AI+向量化
  • 超算中尝试安装dify(失败)
  • Windows编译安装ffmpeg和sdl
  • 电子电气架构 --- 软件项目变更管理
  • Squid服务配置代理
  • 荣耀平板儿童限制
  • 温度影响的材料合成与生长-属于动力学控制还是热力学控制