vector详解(C++)

参考:C++ vector链接:http://www.cplusplus.com/reference/vector/vector/

1.vector

vector 是 C++ STL 中一种顺序容器(sequence container),其底层实现基于动态数组。与普通数组不同的是,vector 可以根据需要动态扩展其大小,即它能够存储任意数量的元素,而不需要在创建时指定一个固定的大小。

2 vector 的优点

a.动态扩展
vector 能够自动调整大小,避免了固定大小数组带来的内存不足问题。
b.高效的随机访问
由于 vector 底层是连续的内存块,因此它可以像数组一样通过索引进行快速的随机访问。
c.灵活的插入和删除
vector 支持高效的尾部插入和删除操作,且提供了多种插入、删除方式。
d.STL 兼容性
vector 是 STL 容器,支持 STL 的算法和迭代器,可以与其他 STL 容器和算法无缝结合。

3 vector 的缺点

a.头部和中间的插入、删除效率低:由于 vector 使用连续的内存块,因此在中间或头部插入或删除元素时,需要移动大量元素,时间复杂度为 O(n)
b.内存浪费:为了提高扩展效率,vector 通常会预留比实际需要更多的内存,这可能导致内存浪费。

4 vector 的定义

#include <vector>
std::vector<int> vec;          // 定义一个存储整数的空vector
std::vector<int> vec(10);      // 定义一个包含10个元素的vector,元素值默认初始化为0
std::vector<int> vec(10, 1);   // 定义一个包含10个元素的vector,元素值为1
std::vector<int> vec2 = vec;   // 定义一个新vector,并通过拷贝构造函数初始化

5 基本操作

push_back():在 vector 的末尾插入元素。
pop_back():删除 vector 末尾的元素。
size():返回 vector 中元素的数量。
capacity():返回 vector 当前的容量,即它在不重新分配内存的情况下最多可以容纳的元素数。
clear():清空 vector 中的所有元素。
empty():判断 vector 是否为空。
resize():调整 vector 的大小。
reserve():为 vector 预留一定的容量,避免频繁的重新分配内存。
shrink_to_fit():清理没有使用的空间

6 迭代器的使用

begin()
end()
rbegin()
rend()

7 vector 动态数组的实现

vector 的底层实现基于动态数组。当需要插入新元素时,如果当前容量不足,vector 会自动分配更大的内存块,并将原来的元素拷贝到新的内存块中。这种动态扩展策略的时间复杂度较低,因为 vector 的容量在每次扩展时通常是当前容量的两倍

std::vector<int> vec;
vec.push_back(1);  // 第一次插入,分配内存
vec.push_back(2);  // 插入,内存足够,不需要重新分配
vec.push_back(3);  // 
// 当容量不足时,vector 会重新分配内存,通常是原来容量的两倍。

8 vector 内存管理

vector 通过 capacity 来控制当前分配的内存大小,而 size 表示实际存储的元素数量。capacity 总是大于或等于 size。当 size 超过 capacity 时,vector 会重新分配内存,并将所有现有元素拷贝到新的内存地址。

std::vector<int> vec;
vec.reserve(10);  // 预先分配10个元素的内存
vec.push_back(1); // 不会触发内存重新分配
vec.push_back(2); // 不会触发内存重新分配

9 vector 插入元素

vec.push_back(1);  // 尾部插入1,时间复杂度 O(1)
vec.pop_back(1);  // 移除尾部,时间复杂度 O(1)
vec.insert(vec.begin() + 1, 10);  // 在第二个位置插入10,后面的元素都需要向后移动,O(n)
vec.erase(vec.begin() + 2);       // 删除第三个元素,后面的元素都需要向前移动,O(n)

10 vector 拷贝复制和move

// 当一个 vector 被赋值或复制时,会创建一个新对象,并将所有元素进行深拷贝。这意味着修改新对象不会影响原来的 vector。
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = vec1;   // 深拷贝
vec2[0] = 10;
std::cout << vec1[0];  // 输出1,vec1不受影响// C++11 引入了移动语义,允许将 vector 的资源直接转移到另一个对象,而不需要进行深拷贝。这可以极大地提高性能,尤其是在处理大型对象时。
std::vector<int> vec1 = {1, 2, 3};
std::vector<int> vec2 = std::move(vec1);  // 使用std::move,vec1的资源转移给vec2

11 emplace_back() 与 push_back() 的区别

emplace_back() 是 C++11 新增的功能,它允许直接在容器的末尾构造对象,而无需先构造对象再拷贝到 vector。相比之下,push_back() 会进行额外的拷贝操作,因此在某些情况下,emplace_back() 会比 push_back() 更高效。

class Person {
public:Person(const std::string& name, int age) : name(name), age(age) {}
private:std::string name;int age;
};// 使用push_back
std::vector<Person> people;
people.push_back(Person("John", 30));  // 先构造Person对象,然后拷贝到vector中// 使用emplace_back
people.emplace_back("Jane", 25);  // 直接在vector内部构造Person对象,避免拷贝

12 shrink_to_fit() 减少容量浪费

由于 vector 通常会预留比实际所需更多的内存空间(capacity()),可能会造成内存浪费。shrink_to_fit() 函数用于释放未使用的内存,使得 vector 的容量等于其大小。

std::vector<int> vec = {1, 2, 3};
vec.reserve(10);   // 预留10个元素的空间
std::cout << vec.capacity();  // 输出10vec.shrink_to_fit();
std::cout << vec.capacity();  // 输出3,容量被调整为实际使用的大小

13 vector 常见陷阱

a.容量浪费问题
vector 的容量通常大于其实际存储的元素数量。如果程序中频繁进行插入操作且对内存使用敏感,可以使用 shrink_to_fit() 来减少浪费。
b.迭代器失效(最需要注意的地方)
在 vector 中进行插入或删除操作时,所有指向 vector 元素的迭代器、指针或引用可能会失效。这是因为插入或删除操作可能导致 vector 重新分配内存,从而改变所有元素的地址。

std::vector<int> vec = {1, 2, 3};
auto it = vec.begin();
vec.push_back(4);  // 可能导致内存重新分配
std::cout << *it;  // 迭代器可能失效,行为未定义

c.元素的析构
当 vector 中的对象被删除时,会调用对象的析构函数。因此,如果 vector 存储的是指针类型,在删除 vector 或清空元素时需要特别小心,确保不会引发内存泄漏。

std::vector<int*> vec;
vec.push_back(new int(10));
vec.clear();  // 仅删除了指针,但没有释放内存,可能导致内存泄漏

解决方案是在删除元素之前手动释放内存,或者使用智能指针。

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

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

相关文章

PostgreSQL主从复制配置

本文主要介绍基于pg_basebackup实现主从复制&#xff08;异步流复制&#xff09; MASTER节点安装的方法可以看这篇文章 PostgreSQL YUM安装_yum install postgresql-CSDN博客 关于基本的配置就不作过多的介绍了&#xff0c;直接开始 MASTER节点 首先在master节点创建一个用于…

2025 OWASP十大智能合约漏洞

随着去中心化金融&#xff08;DeFi&#xff09;和区块链技术的不断发展&#xff0c;智能合约安全的重要性愈发凸显。在此背景下&#xff0c;开放网络应用安全项目&#xff08;OWASP&#xff09;发布了备受期待的《2025年智能合约十大漏洞》报告。 这份最新报告反映了不断演变的…

关于WPF中ComboBox文本查询功能

一种方法是使用事件&#xff08;包括MVVM的绑定&#xff09; <ComboBox TextBoxBase.TextChanged"ComboBox_TextChanged" /> 然而运行时就会发现&#xff0c;这个事件在疯狂的触发&#xff0c;很频繁 在实际应用中&#xff0c;如果关联查询数据库&#xff0…

[Qt]系统相关-网络编程-TCP、UDP、HTTP协议

目录 前言 一、UDP网络编程 1.Qt项目文件 2.UDP类 QUdpSocket QNetworkDatagram 3.UDP回显服务器案例 细节 服务器设计 客户端设计 二、TCP网络编程 1.TCP类 QTcpServer QTcpSocket 2.TCP回显服务器案例 细节 服务器设计 客户端设计 三、HTTP客户端 1.HTTP…

【LeetCode】--- MySQL刷题集合

1.组合两个表&#xff08;外连接&#xff09; select p.firstName,p.lastName,a.city,a.state from Person p left join Address a on p.personId a.personId; 以左边表为基准&#xff0c;去连接右边的表。取两表的交集和左表的全集 2.第二高的薪水 &#xff08;子查询、if…

【2024年华为OD机试】(B卷,100分)- 数据分类 (Java JS PythonC/C++)

一、问题描述 题目描述 对一个数据a进行分类,分类方法为: 此数据a(四个字节大小)的四个字节相加对一个给定的值b取模,如果得到的结果小于一个给定的值c,则数据a为有效类型,其类型为取模的值;如果得到的结果大于或者等于c,则数据a为无效类型。 比如一个数据a=0x010…

Java 8 实战 书籍知识点散记

一、Lambda表达式 1.1 Lambda表达式的一些基本概念 1.2 Lambda表达式的三个部分 // 简化前Comparator<Apple> byWeightnew Comparator<Apple>() {public int compare(Apple a1, Apple a2){return a1.getWeight().compareTo(a2.getWeight());}};//Lambda表达式Comp…

大数据中 TopK 问题的常用套路

大数据中 TopK 问题的常用套路 作者 Chunel Feng&#xff0c;编程爱好者&#xff0c;阿里巴巴搜索引擎开发工程师。开源项目&#xff1a;Caiss 智能相似搜索引擎 对于海量数据到处理经常会涉及到 topK 问题。在设计数据结构和算法的时候&#xff0c;主要需要考虑的应该是当前算…

GPU算力平台|在GPU算力平台部署MedicalGPT医疗大模型的应用教程

文章目录 一、GPU算力服务平台云端GPU算力平台 二、平台账号注册流程MedicalGPT医疗大模型的部署MedicalGPT医疗大模型概述MedicalGPT部署步骤 一、GPU算力服务平台 云端GPU算力平台 云端GPU算力平台专为GPU加速计算设计&#xff0c;是一个高性能计算中心&#xff0c;广泛应用…

Python - itertools- pairwise函数的详解

前言&#xff1a; 最近在leetcode刷题时用到了重叠对pairwise,这里就讲解一下迭代工具函数pairwise,既介绍给大家&#xff0c;同时也提醒一下自己&#xff0c;这个pairwise其实在刷题中十分有用&#xff0c;相信能帮助到你。 参考官方讲解&#xff1a;itertools --- 为高效循…

DEBERTA:具有解耦注意力机制的解码增强型BERT

摘要 近年来&#xff0c;预训练神经语言模型的进展显著提升了许多自然语言处理&#xff08;NLP&#xff09;任务的性能。本文提出了一种新的模型架构DeBERTa&#xff08;具有解耦注意力机制的解码增强型BERT&#xff09;&#xff0c;通过两种新技术改进了BERT和RoBERTa模型。第…

鸿蒙模块概念和应用启动相关类(HAP、HAR、HSP、AbilityStage、UIAbility、WindowStage、window)

目录 鸿蒙模块概念 HAP entry feature har shared 使用场景 HAP、HAR、HSP介绍 HAP、HAR、HSP开发 应用的启动 AbilityStage UIAbility WindowStage Window 拉起应用到显示到前台流程 鸿蒙模块概念 HAP hap包是手机安装的最小单元&#xff0c;1个app包含一个或…

[OpenGL]实现屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO)

一、简介 本文介绍了 屏幕空间环境光遮蔽(Screen-Space Ambient Occlusion, SSAO) 的基本概念&#xff0c;实现流程和简单的代码实现。实现 SSAO 时使用到了 OpenGL 中的延迟着色 &#xff08;Deferred shading&#xff09;技术。 按照本文代码实现后&#xff0c;可以实现以下…

MATLAB绘图时线段颜色、数据点形状与颜色等设置,介绍

MATLAB在绘图时&#xff0c;设置线段颜色和数据点的形状与颜色是提高图形可读性与美观性的重要手段。本文将详细介绍如何在 MATLAB 中设置这些属性。 文章目录 线段颜色设置单字母颜色表示法RGB 值表示法 数据点的形状与颜色设置设置数据点颜色和形状示例代码 运行结果小结 线段…

AIGC视频生成国产之光:ByteDance的PixelDance模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍ByteDance的视频生成模型PixelDance&#xff0c;论文于2023年11月发布&#xff0c;模型上线于2024年9月&#xff0c;同时期上线的模型还有Seaweed&…

mac 电脑上安装adb命令

在Mac下配置android adb命令环境&#xff0c;配置方式如下&#xff1a; 1、下载并安装IDE &#xff08;android studio&#xff09; Android Studio官网下载链接 详细的安装连接请参考 Mac 安装Android studio 2、配置环境 在安装完成之后&#xff0c;将android的adb工具所在…

# [0114] Task01 《数学建模导论》P1 解析几何与方程模型

链接&#xff1a;https://www.datawhale.cn/activity/124 整理的相关代码库 GitHub 页面链接 绪论 姜启源&#xff1a;“数学建模就是建立数学模型解决实际问题” 本质还是解应用题&#xff0c;只是曾经的“小明买糖”变成了如今的“嫦娥探月”。 SEIR 模型&#xff0c;也…

NewStar CTF week1 web wp

谢谢皮蛋 做这题之前需要先去学习一些数据库的知识 1 order by 2 1可以理解为输入的id&#xff0c;是一个占位符&#xff0c;按第二列排序用来测试列数&#xff0c;如果没有两列则会报错-1 union select 1,2 -1同样是占位符&#xff0c;union的作用是将注入语句合并到原始语句…

备赛蓝桥杯之第十五届职业院校组省赛第二题:分享点滴

提示&#xff1a;本篇文章仅仅是作者自己目前在备赛蓝桥杯中&#xff0c;自己学习与刷题的学习笔记&#xff0c;写的不好&#xff0c;欢迎大家批评与建议 由于个别题目代码量与题目量偏大&#xff0c;请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题&#xff0…

C语言初阶牛客网刷题——JZ17 打印从1到最大的n位数【难度:入门】

1.题目描述 牛客网OJ题链接 题目描述&#xff1a; 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 用返回一个整数列表来代替打印n 为正整数&#xff0c;0 < n < 5 示例1 输入&…