vector容器resize和reserve方法的区别

本文详细解析了C++中vector容器的工作原理,包括其自动扩容机制、resize与reserve的区别,以及clear方法的行为。通过具体代码示例展示了vector在不同操作下的size与capacity变化。

        vector可以理解为,可以自动扩容的数组。但是因为数据在堆上,所以每次扩容需要经历,申请内存,拷贝数据,释放内存的过程。

        vector提供两个方法,resize和reverse方法。resize执行扩容操作并且自动执行构造函数。reverse仅仅修改容量大小,及vector的capacity的大小。vector的clear方法,仅仅修改有效数据数量,不回收内存。

    cout<<"veValuesOne   resize"<<endl;
	vector<int> veValuesOne;
	cout<<"size:"<<veValuesOne.size() <<"   cap:"<<veValuesOne.capacity()<<endl;
	veValuesOne.resize(10);
	cout<<"size:"<<veValuesOne.size() <<"   cap:"<<veValuesOne.capacity()<<endl;
	cout<<veValuesOne.at(5)<<endl;

	cout<<"veValuesTwo   reserve"<<endl;
	vector<int> veValuesTwo;
	cout<<"size:"<<veValuesTwo.size() <<"   cap:"<<veValuesTwo.capacity()<<endl;
	veValuesTwo.reserve(10);
	cout<<"size:"<<veValuesTwo.size() <<"   cap:"<<veValuesTwo.capacity()<<endl;
	//cout<<veValuesTwo
<think>我们正在讨论C++中std::vectorresizereserve方法区别。 首先,这两个方法都用于管理vector的内存,但它们的用途效果有显著不同。 1. resize方法: - 作用:改变vector中元素的数量(即size)。 - 如果新的size比当前size大,则会在vector的末尾添加新的元素(默认初始化或指定值),这可能会导致重新分配内存(如果capacity不足)。 - 如果新的size比当前size小,则删除多余的元素(从末尾删除),但capacity不变(内存不释放)。 - 语法:void resize(size_type n, value_type val = value_type()); - n: 新的size大小 - val: 可选,当需要增加元素时,新元素初始化为val的副本;如果不提供,则使用默认构造函数初始化。 2. reserve方法: - 作用:改变vector的容量(capacity),即预分配内存。 - 如果n大于当前capacity,则重新分配内存,使得capacity至少为n(可能更大,取决于实现)。 - 如果n小于等于当前capacity,则不做任何事(不会缩小capacity)。 - 语法:void reserve(size_type n); - n: 新的capacity大小(最少要预留的空间) 关键区别: - resize改变的是vector中元素的数量(size),而reserve改变的是内存容量(capacity),不改变元素数量。 - resize可能会增加元素(并初始化),也可能会减少元素(销毁多余元素);reserve只是预留内存空间,不会创建或销毁任何元素。 - 使用reserve可以避免多次重新分配内存(例如,在已知要存储大量元素时,提前reserve可以避免多次动态扩容的开销)。 示例: std::vector<int> vec; vec.reserve(100); // 预留100个int的空间,但vec.size()仍为0 vec.resize(50); // 现在vec有50个元素,每个元素初始化为0(int的默认值),capacity至少100 vec.resize(100, 1); // 将元素数量增加到100,新增的50个元素初始化为1 注意: - 在reserve之后,vector的size不变,因此我们不能使用下标访问(如vec[i])来设置元素(因为还没有元素),应该使用push_back或者resize后再使用下标。 - resize(n)会调用元素的默认构造函数(如果元素是类类型)来初始化新元素,或者使用指定的值。 性能提示: 频繁的重新分配内存(例如,在循环中不断push_back导致多次扩容)会降低性能。因此,如果预先知道元素的大致数量,使用reserve可以显著提高性能。 另外,C++11引入了shrink_to_fit方法,可以用来减少capacity以匹配size(但这是非强制性的请求,具体取决于实现)。 §§相关问题§§ 1. 在std::vector中,capacity()size()方法分别返回什么?它们有何区别? 2. 使用resize方法增加vector的大小时,新添加的元素如何初始化? 3. 调用reserve(100)后立即调用resize(50),此时vector的capacitysize分别是多少? 4. 如何减少std::vector占用的内存空间(即缩小capacity)? 5. 在什么情况下,使用reserve比让vector自动扩容更高效? </think>### `std::vector` 中 `resize` 与 `reserve` 的区别详解 #### **核心概念对比** | **特性** | `resize(n)` | `reserve(n)` | |------------------|-------------------------------------|-----------------------------------| | **作用对象** | 改变元素数量(`size`) | 改变内存容量(`capacity`) | | **元素操作** | 增删元素(构造/析构) | ❌ 不操作元素(仅预分配内存) | | **访问安全** | ✅ 新元素可立即访问(如 `v[0]`) | ❌ 未初始化内存(访问导致未定义行为)| | **内存分配触发** | 若 `n > capacity` 则自动重新分配 | 仅在 `n > capacity` 时分配 | | **缩小操作** | ✅ 可减少 `size`(析构多余元素) | ❌ 无法缩小 `capacity` | --- #### **一、`resize`:调整元素数量(`size`)** ```cpp void resize(size_type n, value_type val = value_type()); ``` 1. **行为逻辑**: - 若 `n > size()`:添加 `n - size()` 个元素(默认构造或拷贝 `val`) - 若 `n < size()`:删除末尾 `size() - n` 个元素(调用析构函数) - 若 `n == size()`:无操作 2. **内存影响**: - 可能触发内存重新分配(当 `n > capacity()` 时) - `capacity()` **可能增加**,但**不会减少** 3. **示例**: ```cpp std::vector<int> v = {1, 2, 3}; v.resize(5); // size=5, 添加两个0 → [1,2,3,0,0] v.resize(2, 100); // size=2, 删除末尾3个 → [1,2](参数100无效) ``` --- #### **二、`reserve`:预分配内存(`capacity`)** ```cpp void reserve(size_type n); ``` 1. **行为逻辑**: - 若 `n > capacity()`:分配至少能容纳 `n` 个元素的内存 - 若 `n <= capacity()`:无操作 2. **内存影响**: - 仅扩大 `capacity()`(不会减少) - `size()` **不变**,元素未被修改 3. **核心用途**: - **避免反复扩容**:在已知元素数量时预分配内存,提升性能 ```cpp std::vector<int> v; v.reserve(1000); // 一次性分配1000个元素的内存 for (int i=0; i<1000; ++i) { v.push_back(i); // 无扩容开销 } ``` --- #### **三、关键区别场景** ##### 1. **元素初始化** - `resize`:新增元素被**显式构造**(默认值或指定值) - `reserve`:仅分配**未初始化内存**(元素不存在) ##### 2. **访问安全性** ```cpp std::vector<int> v; v.reserve(10); // v[0] = 1; // ❌ 错误:访问未初始化内存(UB) v.resize(10); v[0] = 1; // ✅ 安全:元素已默认初始化为0 ``` ##### 3. **性能优化** - `reserve`:适用于**已知最终元素数量**的场景(减少 `push_back` 的多次扩容) - `resize`:适用于**立即需要访问元素**的场景 --- #### **四、常见误区** 1. **`reserve` 后直接访问元素**: ```cpp v.reserve(10); v[0] = 42; // ❌ 未定义行为(实际元素未被构造) ``` 2. **缩小 `capacity`**: - `resize` `reserve` **均无法缩小容量** - 需用 `shrink_to_fit()`(C++11)请求缩小: ```cpp v.shrink_to_fit(); // 请求调整 capacity() 匹配 size() ``` --- #### **五、总结选择策略** - 需**立即操作元素** → 用 `resize` - 需**预分配内存避免扩容** → 用 `reserve` - 需**释放多余内存** → `shrink_to_fit()`(但非强制)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值