【C++】:STL详解 —— vector类

目录

vector的概念

vector的构造函数 

vector的大小

size()和capacity()

empty()

resize()和reserver()

vector的插入

push_back()和emplace_back()

insert()和emplace()

vector的删除

pop_back()

earse()

clear()

vector的迭代器

迭代器类型

begin()和end()

rbegin()和end()

vector中元素的访问

[]+下标

at()

front()和back()

越界访问风险与防护

 性能与适用场景对比

vector迭代器失效问题

迭代器失效的场景

安全操作的最佳实践

迭代器失效规则总结


vector的概念

  1. vector是表示可变大小数组的序列容器
  2. vector就像数组一样,也采用的连续空间来存储元素,这也意味着可以采用下标对vector的元素进行访问
  3. vector与普通数组不同的是,vector的大小是可以动态改变
  4. 当vector需要重新分配大小时,其做法是,分配一个新的数组,然后将全部元素移到这个数组当中,并释放原来的数组空间
  5. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因此存储空间比实际需要的存储空间一般更大。不同的库采用不同的策略权衡空间的使用和重新分配,以至于在末尾插入一个元素的时候是在常数的时间复杂度完成的
  6. 由于vector采用连续的空间来存储元素,与其他动态序列容器相比,vector在访问元素的时候更加高效,在其末尾添加和删除元素相对高效,而对于不在其末尾进行的删除和插入操作效率则相对较低
     

vector的构造函数 

    // 默认构造vector<int> v1;// 指定元素个数和值vector<int> v2(3, 100);       // {100, 100, 100}// 迭代器范围构造list<int> lst = {1, 2, 3};vector<int> v3(lst.begin(), lst.end()); // {1, 2, 3}// 拷贝构造vector<int> v4(v3);           // {1, 2, 3}// 移动构造vector<int> v5(move(v4));      // v5 接管 v4 的内存,v4 变空// 初始化列表构造vector<int> v6 = {4, 5, 6};   // {4, 5, 6}// 类型推导构造(C++17)vector v7 = {7, 8, 9};        // vector<int>
构造函数形式作用描述时间复杂度C++版本要求
vector<T>()创建空 vectorO(1)C++98
vector<T>(n)创建 n 个默认元素的 vectorO(n)C++98
vector<T>(n, val)创建 n 个 val 值的 vectorO(n)C++98
vector<T>(first, last)迭代器范围初始化O(n)C++98
vector<T>(const vector&)深拷贝构造O(n)C++98
vector<T>(vector&&)移动构造(高效转移内存)O(1)C++11
vector<T>{elem1, elem2...}初始化列表构造O(n)C++11
vector{...}类型自动推导O(n)C++17

vector的大小

size()和capacity()

  • size():返回当前元素数量
  • capacity():返回当前预分配的内存容量(可容纳的最大元素数)

vector<int> v = {1, 2, 3};
cout << v.size();   // 输出 3
cout << v.capacity();   // 输出 3

empty()

判断vector是否为空(size==0)

vector<int> v = {1, 2, 3};
cout << v.empty();  // 输出 0(false)

resize()和reserver()

  • resize(n):调整元素数量为 n

    • 若 n > size(),新增元素默认初始化(如 int 初始化为 0)。

    • 若 n < size(),删除尾部多余元素。

  • reserve(n):预分配至少能容纳 n 个元素的内存(减少扩容次数)。

vector<int> v = {1, 2, 3};
v.resize(5);        // v = {1, 2, 3, 0, 0}
v.resize(2);        // v = {1, 2}
v.reserve(100);     // 预分配容量为 100
cout << v.capacity(); // 输出 100
操作/属性描述示例
size()当前元素数量v.size() → 3
capacity()当前预分配内存可容纳的元素数量v.capacity() → 5
resize(n)调整元素数量(可能增删元素)v.resize(5) → 5 个元素
reserve(n)预分配内存容量(不改变元素数量)v.reserve(10)

vector的插入

push_back()和emplace_back()

  • push_back(const T& value)       
    • 在尾部插入元素(拷贝构造)。
  • emplace_back(Args&&... args)(C++11 起)
    • 在尾部直接构造元素(避免临时对象拷贝)

vector<int> v = {1, 2};
v.push_back(3);          // v = {1, 2, 3}(拷贝)
v.emplace_back(4);       // v = {1, 2, 3, 4}(直接构造)

insert()和emplace()

  • insert(iterator pos, const T& value)  
    • 在迭代器 pos 指向的位置前插入元素(拷贝构造)。
  • emplace(iterator pos, Args&&... args)(C++11 起)
    • 在 pos 位置直接构造元素(更高效)。

vector<int> v = {1, 3};
auto it = v.begin() + 1;
v.insert(it, 2);         // v = {1, 2, 3}(在位置1插入2)
v.emplace(it, 0);        // v = {1, 0, 2, 3}(在位置1插入0)

vector的删除

pop_back()

移除最后一个元素

vector<int> v = {1, 2, 3};
v.pop_back();   // v = {1, 2}

earse()

erase(iterator pos)
删除迭代器 pos 指向的元素,返回指向下一个元素的迭代器。

vector<int> v = {1, 2, 3, 4};
auto it = v.begin() + 1;
it = v.erase(it);    // 删除元素 2,v = {1, 3, 4}// it 指向 3(需更新迭代器)

erase(iterator first, iterator last)
删除迭代器范围 [first, last) 内的元素,返回指向 last 之后元素的迭代器。

vector<int> v = {1, 2, 3, 4, 5};
auto it = v.erase(v.begin() + 1, v.begin() + 3); 
// 删除元素 2 和 3,v = {1, 4, 5}
// it 指向 4

clear()

移除所有元素,size() 变为 0,但 capacity() 保持不变。

vector<int> v = {1, 2, 3};
v.clear();       // v 为空,size=0,capacity 仍为 3

vector的迭代器

迭代器类型

vector<T>::iterator:普通迭代器(可读写元素)。vector<T>::const_iterator:常量迭代器(只读元素)。vector<T>::reverse_iterator:反向迭代器。vector<T>::const_reverse_iterator:常量反向迭代器。
vector<int> v = {1, 2, 3};vector<int>::iterator it = v.begin();
*it = 10;  // 修改元素为 10vector<int>::const_iterator cit = v.cbegin();
// *cit = 20;  // 错误!不可修改

begin()和end()

  • begin():返回指向第一个元素的迭代器。

  • end():返回指向最后一个元素之后位置的迭代器(尾后迭代器)。

iterator begin();
const_iterator begin() const;iterator end();
const_iterator end() const;
vector<int> v = {1, 2, 3};// 正向遍历
for (auto it = v.begin(); it != v.end(); ++it) {cout << *it << " ";  // 输出 1 2 3
}

rbegin()和end()

  • rbegin():返回指向最后一个元素之后位置的迭代器(尾后迭代器)。

  • rend():返回指向第一个元素的迭代器。

iterator rbegin();
const_iterator begin() const;iterator rend();
const_iterator end() const;
// 反向遍历
for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {cout << *rit << " "; // 输出 3 2 1
}

vector中元素的访问

[]+下标

  • 高效:时间复杂度 O(1)(直接计算内存偏移)。

  • 无边界检查:越界访问导致未定义行为(可能崩溃或数据损坏)。

reference operator[] (size_type n);
const_reference operator[] (size_type n) const;
vector<int> v = {10, 20, 30};
cout << v[0];    // 输出 10
v[1] = 200;      // 修改元素为 200
// cout << v[5];  // 危险!越界访问

at()

  • 边界检查:若 index >= size(),抛出 std::out_of_range 异常。

  • 性能略低:因额外检查,稍慢于 operator[]

vector<int> v = {1, 2, 3};
try {cout << v.at(2);  // 输出 3cout << v.at(5);  // 抛出异常
} catch (const out_of_range& e) {cerr << "越界错误:" << e.what(); // 捕获异常
}

front()和back()

  • front():返回第一个元素的引用。

  • back():返回最后一个元素的引用。

vector<int> v = {5, 6, 7};
cout << v.front();  // 5
cout << v.back();   // 7
v.front() = 0;      // v = {0, 6, 7}
// 若 vector 为空,行为未定义!

越界访问风险与防护

访问方法越界行为安全建议
operator[]未定义行为(崩溃/数据损坏)确保索引有效(如 index < v.size()
at()抛出异常使用 try-catch 处理异常
front()/back()空容器导致未定义行为先检查 !v.empty()

 性能与适用场景对比

方法性能安全性典型场景
operator[]无检查已知索引安全的快速访问
at()高(异常)需边界检查的调试或不确定索引
迭代器/范围 for依赖遍历逻辑顺序访问或修改元素
data()无检查与 C 风格 API 交互(如 memcpy

vector迭代器失效问题

迭代器的主要作用就是让我们在使用各个容器时不用关心其底层的数据结构,而vector的迭代器在底层实际上就是一个指针。迭代器失效就是指迭代器底层对应指针所指向的空间被销毁了,而指向的是一块已经被释放的空间,如果继续使用已经失效的迭代器,程序可能会崩溃。

迭代器失效的场景

1、插入操作(Insert)

导致扩容:插入元素时若超出当前容量(size >= capacity),vector会重新分配内存,导致所有迭代器、指针、引用失效

vector<int> v = {1, 2, 3};
auto it = v.begin();
v.push_back(4);  // 假设容量不足,触发扩容
// it 失效!不可使用

未扩容时:仅插入位置之后的迭代器失效。

vector<int> v = {1, 2, 3};
v.reserve(5);          // 预分配容量
auto it = v.begin() + 1;
v.insert(it, 4);       // 插入后,it 及其后的迭代器失效
// 必须使用 insert 返回的新迭代器
auto new_it = v.insert(v.begin() + 1, 4);

2、删除操作(Erase)

删除元素时,被删除元素之后的迭代器失效,包括end()

vector<int> v = {1, 2, 3, 4};
auto it = v.begin() + 2;  // 指向3
v.erase(it);             // 删除3,it失效
// 必须使用 erase 返回的迭代器(指向4)
it = v.erase(it);        // it 现在指向4

3、容量调整(Resize/Reserve)

  • reserve(n):若 n > capacity,重新分配内存,所有迭代器失效。

  • resize(n):若 n > capacity,同样触发扩容,导致所有迭代器失效

安全操作的最佳实践

使用迭代器时,永远记住一句话:每次使用前,对迭代器进行重新赋值

1、插入操作(Insert)

使用返回的新迭代器更新原迭代器:

vector<int> v = {1, 3, 4};
auto it = v.begin() + 1;
it = v.insert(it, 2);  // v = {1,2,3,4}, it指向2

2、删除操作(Erase)

在循环中结合erase的返回值更新迭代器:

vector<int> v = {2, 4, 6, 8};
for (auto it = v.begin(); it != v.end();) 
{if (*it % 2 == 0) {it = v.erase(it);  // 更新迭代器} else {++it;}
}

迭代器失效规则总结

操作迭代器失效范围内存是否重分配
push_back/emplace_back若扩容则全部失效;否则仅end()失效可能
insert/emplace若扩容则全部失效;否则插入点之后失效可能
erase/pop_back被删除元素之后失效
reserve(n > capacity)全部失效
resize(n > capacity)全部失效

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/23950.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【时时三省】(C语言基础)常量和变量

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 在计算机高级语言中&#xff0c;数据有两种表现形式&#xff1a;常量和变量。 常量 在程序运行过程中&#xff0c;其值不能被改变的量称为常量。数值常量就是数学中的常数。 常用的常量有以…

zabbix故障案例 WEB页面Database error Connection refused

目录 1.思路 2.问题解决 3.其他数据库问题思路 1.思路 当我们遇到 Database error Connection refused的问题的时候一般想到的都是数据库的问题 那我们这时候就顺着这条线索排查 2.问题解决 我们首先先进入数据库 mysql -uzabbix -p123 发现了如下报错 应该是数…

MaxKB+Ollama+DeepSeek1.5B部署知识库

环境信息 练习测试用&#xff0c;所以资源很低&#xff0c;8G显卡。大模型部署在Windows台式机上&#xff0c;MaxKB部署在CentOS虚拟机上。 台式机&#xff1a; 硬件&#xff1a;i7 13900 NV GeForce RTX 3060 Ti 8G显存 32G内存 软件&#xff1a;Windows 11操作系统&…

猿大师播放器:智慧交通Web网页低延迟播放监控RTSP H.265视频解决方案

在智慧城市建设加速推进的今天&#xff0c;智慧交通作为城市"神经系统"正面临前所未有的发展机遇。据统计&#xff0c;2023年全国交通视频监控设备保有量已突破4500万台&#xff0c;日均产生的视频数据量超50PB。但在这些庞大数字背后&#xff0c;行业却普遍面临着&q…

Web3.py 入门笔记

Web3.py 学习笔记 &#x1f4da; 1. Web3.py 简介 &#x1f31f; Web3.py 是一个 Python 库&#xff0c;用于与以太坊区块链进行交互。它就像是连接 Python 程序和以太坊网络的桥梁。 官方文档 1.1 主要功能 查询区块链数据&#xff08;余额、交易等&#xff09;发送交易与…

如何选择工控产线安全软件?

在当今数字化时代&#xff0c;信息安全的重要性不言而喻。随着工业控制系统&#xff08;ICS&#xff09;的广泛应用&#xff0c;主机的安全加固成为了保障企业生产运营稳定的关键环节。MCK-T主机加固系统软件&#xff0c;凭借其卓越的性能和全面的安全防护功能&#xff0c;成为…

系统调用过程

注意&#xff1a;本系统调用过程基于32位操作系统 中断服务程序的寻址过程 1.用户态程序产生系统调用write()&#xff1b; 2.产生中断指令ENTER_KERNEL(int $0x80128)&#xff0c;CPU收到中断指令去查询中断向量表&#xff0c;找出中断号0x80对应的中断服务程序的内存基地址(0…

PHP入门基础学习七(函数3)

九、数组函数 1、合并两个数组 合并两个数组,其中一个当健名,一个当值 注意: array_combine 函数,通过合并两个数组来创建一个新数组,其中的一个数组是键名,另一个数组的值为键值。 2.1、排序函数 对于数组的排序,除了可使用前面讲解的排序算法实现外,PHP还提供了内置…

pycharm管理虚拟环境

不借用Anoconda 1.检查pip所在位置&#xff0c; 因为pip的默认安装路径是python的安装目录下的依赖库路径D:\Program Files\Python397\Lib\site-packages。项目如果用之前pycharm创建的环境是无法加载这个路径的库的。 2.安装时指定安装路径 千万要注意指定安装路径为项目的…

DeepSeek 助力 Vue 开发:打造丝滑的 复选框(Checkbox)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

FMT源码 - module

module 功能模块 1、uMCN uMCN 是 类似于 PX4里面的 uORB 模块。 mcn listmcn echo sensor_imu0mcn echo <topic> [options]options:-n, --number Set topic echo number, e.g, -n 10 will echo 10 times. (朝终端打印的次数)-p, --period Set topic echo peri…

城电科技|会追日的智能花,光伏太阳花开启绿色能源新篇章

当艺术与科技相遇&#xff0c;会碰撞出怎样的火花&#xff1f;城电科技推出的光伏太阳花&#xff0c;以其独特的设计与智能化的功能&#xff0c;给出了答案。这款产品不仅具备太阳能发电的实用功能&#xff0c;更是一件充满科技属性的艺术性光伏产品&#xff0c;吸引了广泛关注…

湖北中医药大学谱度众合(武汉)生命科技有限公司研究生工作站揭牌

2025年2月11日&#xff0c;湖北中医药大学&谱度众合&#xff08;武汉&#xff09;生命科技有限公司研究生工作站揭牌仪式在武汉生物技术研究院一楼101会议室举行&#xff0c;湖北中医药大学研究生院院长刘娅教授、基础医学院院长孔明望教授、基础医学院赵敏教授、基础医学院…

计算机网络————(一)HTTP讲解

基础内容分类 从TCP/IP协议栈为依托&#xff0c;由上至下、从应用层到基础设施介绍协议。 1.应用层&#xff1a; HTTP/1.1 Websocket HTTP/2.0 2.应用层的安全基础设施 LTS/SSL 3.传输层 TCP 4.网络层及数据链路层 IP层和以太网 HTTP协议 网络页面形成基本 流程&#xff1a…

货车一键启动无钥匙进入手机远程启动的正确使用方法

一、移动管家货车无钥匙进入系统的使用方法 基本原理&#xff1a;无钥匙进入系统通常采用RFID无线射频技术和车辆身份识别码识别系统。车钥匙需要随身携带&#xff0c;当车钥匙靠近货车时&#xff0c;它会自动与货车的解码器匹配。开门操作&#xff1a;当靠近货车后&#xff0…

2.2logstash规则配置

工作流程 Logstash工作的三个阶段&#xff1a; input数据输入端&#xff0c;以接收来自任何地方的源数据 * file&#xff1a;从文件中读取 * syslog&#xff1a;监听在514端口的系统日志信息, 并解析成RFC3164格式 * redis&#xff1a;从redis-server list中获取 * beat&a…

Java进阶:Zookeeper相关笔记

概要总结&#xff1a; ●Zookeeper是一个开源的分布式协调服务&#xff0c;需要下载并部署在服务器上(使用cmd启动&#xff0c;windows与linux都可用)。 ●zookeeper一般用来实现诸如数据订阅/发布、负载均衡、命名服务、集群管理、分布式锁和分布式队列等功能。 ●有多台服…

GB 44497-2024《智能网联汽车 自动驾驶数据记录系统》标准解读

GB 44497-2024《智能网联汽车 自动驾驶数据记录系统》是由工业和信息化部提出并归口的强制性国家标准&#xff0c;由国家市场监督管理总局、国家标准化管理委员会于2024年8月23日批准发布(国家标准公告2024年第18号文)&#xff0c;将于2026年1月1日起实施。标准规定了智能网联汽…

在低功耗MCU上实现人工智能和机器学习

作者&#xff1a;Silicon Labs 人工智能&#xff08;AI&#xff09;和机器学习&#xff08;ML&#xff09;技术不仅正在快速发展&#xff0c;还逐渐被创新性地应用于低功耗的微控制器&#xff08;MCU&#xff09;中&#xff0c;从而实现边缘AI/ML解决方案。这些MCU是许多嵌入式…

[数据结构笔记]数据结构必要的C语言基础

数据结构必要的C语言基础 使用C语言学习数据结构之前有一些必要了解的基础&#xff0c;许多同学在初学数据结构时因为对这些知识不熟&#xff0c;导致了对数据结构的畏惧心理。实际上很大一部分来自C语言的基础 C语言 结构体与指针 ​ 在一些场景中&#xff0c;如果传递给函…