STL的vector::resize() 和 vector::reserve()区别和作用详解

2023-11-01 21:40

本文主要是介绍STL的vector::resize() 和 vector::reserve()区别和作用详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、概述

现在数组基本都用vector了,很方便,但可能对vector的某些属性还不是很了解。以前只是大概知道reserve和resize是分别干什么的,但是并不了解它们的真正目的是什么,今天仔细回顾了一下,终于弄懂了,现在做个记录。

二、区别和作用

1. resize() 设置有效空间,reserve() 设置总体容量

通俗点说,假如蔡徐坤要开演唱会,地点定在了A体育馆,这个体育馆可容纳 5000 5000 5000人。在演唱会开始前卖票,发现销量不是很好,只卖出去了大概 300 300 300张票,但为了保险起见(避免溢出),在体育馆内放置了500把椅子。从这个例子来看,体育馆的 5000 5000 5000人容量是一开始蔡徐坤用 r e s e r v e ( ) reserve() reserve() 申请的 5000 5000 5000人总容量,放置的 500 500 500把椅子,是他用 r e s i z e ( ) resize() resize() 申请的 500 500 500人有效空间。

这里的 5000 5000 5000对应着 v e c t o r : : c a p a c i t y ( ) vector::capacity() vector::capacity(),而 500 500 500对应着 v e c t o r : : s i z e ( ) vector::size() vector::size()

用代码来看看是不是这样

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> concert;concert.reserve(5000);concert.resize(500);cout << "capacity: " << concert.capacity() << endl;cout << "size: " << concert.size() << endl;
}

在这里插入图片描述
后来,蔡徐坤换到了一个大气球里面开演唱会,这个打气球可以尽可能大的膨胀。蔡徐坤一开始只 r e s e r v e ( ) reserve() reserve() 500 500 500人的容量, r e s i z e ( ) resize() resize() 300 300 300个座位,但是发现大家很喜欢这个气球,进来了更多的人,最后一共进来了 800 800 800人,于是他又 r e s i z e ( ) resize() resize() 800 800 800个座位(增加了300个座位),而这个气球(其实已经不是同一个气球了,已经换成了一个更大的气球)也膨胀到了可以容纳下 800 800 800个人。

看看代码

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> concert;concert.reserve(500);concert.resize(300);cout << "capacity: " << concert.capacity() << endl;cout << "size: " << concert.size() << endl;concert.resize(800);cout << endl;cout << "capacity: " << concert.capacity() << endl;cout << "size: " << concert.size() << endl;
}

在这里插入图片描述
可以发现,resize() 调整大小小于 capacity 时,是不会改变 capacity 的,如果大于 capacity 时,则 capacity 也会一起增大。reserve() 的容量大于 capacity 时,也不会改变 size 的,但是如果 reserve 容量小于 resize 呢,答案是也不会改变 size。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> concert;concert.resize(3000);concert.reserve(300);cout << "capacity: " << concert.capacity() << endl;cout << "size: " << concert.size() << endl;
}

在这里插入图片描述

2. vector扩容机制导致迭代器失效

后来,周杰伦也来到了A体育馆开演唱会,因为是暴雨天,以为来的人很好,所以一开始就 r e s i z e ( ) resize() resize() 5000 5000 5000个座位,但是最后却来了 100000 100000 100000名观众,A体育馆容不下这么多人了怎么办,只能大家一起决定搬到另一个可以容纳 100000 100000 100000人的B体育馆。但是当他们全都搬到了B体育馆后,有些迟到的观众并不知道演唱会已经搬走了,他们拿着票才刚来到A体育馆,对着座位号一顿找却没找到座位(椅子已经搬走了),只找到原来椅子地方剩下的一些垃圾,这时候就是迭代器失效了。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> concert;concert.resize(5000); //一开始只放了5000把椅子auto it = concert.begin();cout << *it << endl;concert.resize(100000); // concert.reserve(100000); 效果一样 //后来换了场地,放了100000把椅子cout << *it << endl;
}

在这里插入图片描述
可以看到,当vecor resize()了更大的空间时,会在内从中找另外一块更大的连续内存,然后将数据拷贝过去,此时,在拷贝之前初始化的迭代器 it 仍然停留在原来的地址,所以在数据搬走之后,原来地方的值已经变成了内存中的随机值了。

那么如果周杰伦自信一点,一开始就决定在B体育馆开演唱会,那么也就是一开始就 reserve() 了100000人容量,那么大家也就不会因为场地不够而搬走,迟到的观众也不会找不到座位了。

#include <iostream>
#include <vector>
using namespace std;int main()
{vector<int> concert;concert.reserve(100000); //一开始就申请100000容量concert.resize(5000); //一开始只放了5000把椅子auto it = concert.begin();cout << *it << endl;concert.resize(100000); //reserve()效果一样 //后来调整到100000把椅子cout << *it << endl;
}

在这里插入图片描述
也就是说,一开始就申请足够的容量,就不容易发生数据搬迁拷贝情况,这样,迭代器就不会失效了。

三、总结

reserve() 的作用能够避免不必要的vector扩容,从而避免迭代器失效问题。resize() 调整的是数据的有效空间,对应着size(),而reserve调整的是总容量,对应capacity()。

这篇关于STL的vector::resize() 和 vector::reserve()区别和作用详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/325942

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

在 Spring Boot 中使用 @Autowired和 @Bean注解的示例详解

《在SpringBoot中使用@Autowired和@Bean注解的示例详解》本文通过一个示例演示了如何在SpringBoot中使用@Autowired和@Bean注解进行依赖注入和Bean... 目录在 Spring Boot 中使用 @Autowired 和 @Bean 注解示例背景1. 定义 Stud

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

Go路由注册方法详解

《Go路由注册方法详解》Go语言中,http.NewServeMux()和http.HandleFunc()是两种不同的路由注册方式,前者创建独立的ServeMux实例,适合模块化和分层路由,灵活性高... 目录Go路由注册方法1. 路由注册的方式2. 路由器的独立性3. 灵活性4. 启动服务器的方式5.

Java中八大包装类举例详解(通俗易懂)

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,... 目录一、包装类(Wrapper Class)1、简要介绍2、包装类特点3、包装类用途二、装箱和拆箱1、装