C++ <vector> reserve 函数
reserve 是 vector 中用于预分配内存的重要函数,可以显著提升添加元素的性能。
reserve 是容器类的成员函数,用于预留至少 n 个元素的存储空间。这不会改变容器的大小(size),但会预先分配足够的内存,避免后续添加元素时频繁重新分配。
reserve 是优化 vector 性能的关键函数,特别适合需要添加大量元素的场景。
单词释义: reserve 表示"预留",即预先保留足够的空间。
基本语法与参数
reserve 是容器类的成员函数,需要指定要预留的元素数量。
语法格式
void reserve(size_type n);
参数说明
- 参数:
n- 类型:
size_type(无符号整数类型,通常是size_t) - 描述: 你希望预留的最小元素数量。容器将至少分配能够容纳 n 个元素的内存空间。
- 类型:
函数说明
- 返回值:
void(无返回值)。 - 效果: 容器会重新分配内存,使其容量至少为 n。容器的
size()不会改变,仍是原来的元素数量。 - 注意: 如果 n 小于当前的容量,
reserve不会做任何事情。如果 n 大于当前容量,会重新分配内存。
实例
让我们通过一系列例子,彻底掌握 reserve 的用法。
示例 1:基础用法 - 预分配空间
实例
#include <iostream>
#include <vector>
int main() {
// 创建空 vector
std::vector<int> numbers;
std::cout << "初始状态 - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
// 预留 100 个元素的空间
numbers.reserve(100);
std::cout << "reserve(100) 后 - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
// 添加元素
for(int i = 0; i < 10; ++i) {
numbers.push_back(i);
}
std::cout << "添加 10 个元素后 - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
return 0;
}
#include <vector>
int main() {
// 创建空 vector
std::vector<int> numbers;
std::cout << "初始状态 - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
// 预留 100 个元素的空间
numbers.reserve(100);
std::cout << "reserve(100) 后 - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
// 添加元素
for(int i = 0; i < 10; ++i) {
numbers.push_back(i);
}
std::cout << "添加 10 个元素后 - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
return 0;
}
运行结果预期:
初始状态 - size: 0, capacity: 0 reserve(100) 后 - size: 0, capacity: 100 添加 10 个元素后 - size: 10, capacity: 100
代码解析:
reserve(100)预先分配了能容纳 100 个元素的内存空间。size()仍然是 0,因为还没有添加元素。- 添加 10 个元素后,容量仍然是 100,没有发生内存重新分配。
示例 2:使用 reserve 优化大量数据添加
对于需要添加大量元素的场景,预先使用 reserve 可以显著提升性能。
实例
#include <iostream>
#include <vector>
#include <chrono>
int main() {
const int N = 100000;
// 不使用 reserve
std::vector<int> v1;
auto start1 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v1.push_back(i);
}
auto end1 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1);
// 使用 reserve
std::vector<int> v2;
v2.reserve(N);
auto start2 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v2.push_back(i);
}
auto end2 = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);
std::cout << "不使用 reserve 耗时: " << duration1.count() << " 微秒" << std::endl;
std::cout << "使用 reserve 耗时: " << duration2.count() << " 微秒" << std::endl;
std::cout << "性能提升: " << (double)duration1.count() / duration2.count() << "x" << std::endl;
return 0;
}
#include <vector>
#include <chrono>
int main() {
const int N = 100000;
// 不使用 reserve
std::vector<int> v1;
auto start1 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v1.push_back(i);
}
auto end1 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1);
// 使用 reserve
std::vector<int> v2;
v2.reserve(N);
auto start2 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v2.push_back(i);
}
auto end2 = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);
std::cout << "不使用 reserve 耗时: " << duration1.count() << " 微秒" << std::endl;
std::cout << "使用 reserve 耗时: " << duration2.count() << " 微秒" << std::endl;
std::cout << "性能提升: " << (double)duration1.count() / duration2.count() << "x" << std::endl;
return 0;
}
代码解析:
- 添加 100000 个元素时,预先使用
reserve可以显著减少内存重新分配的次数。 - 这在处理大量数据时能带来明显的性能提升。
示例 3:使用 reserve 的正确方式
要充分发挥 reserve 的作用,应该预先估计需要的容量。
实例
#include <iostream>
#include <vector>
int main() {
// 假设我们要存储 1000 个用户的数据
struct User {
std::string name;
int age;
};
std::vector<User> users;
users.reserve(1000); // 预先分配空间
// 模拟加载用户数据
for(int i = 0; i < 1000; ++i) {
User u;
u.name = "用户" + std::to_string(i);
u.age = 20 + (i % 50);
users.push_back(u);
}
std::cout << "用户数量: " << users.size() << std::endl;
std::cout << "容量: " << users.capacity() << std::endl;
return 0;
}
#include <vector>
int main() {
// 假设我们要存储 1000 个用户的数据
struct User {
std::string name;
int age;
};
std::vector<User> users;
users.reserve(1000); // 预先分配空间
// 模拟加载用户数据
for(int i = 0; i < 1000; ++i) {
User u;
u.name = "用户" + std::to_string(i);
u.age = 20 + (i % 50);
users.push_back(u);
}
std::cout << "用户数量: " << users.size() << std::endl;
std::cout << "容量: " << users.capacity() << std::endl;
return 0;
}
代码解析:
- 对于已知大小的数据加载,预先使用
reserve是最佳实践。 - 这避免了多次内存重新分配,提高了效率。
示例 4:避免不必要的 reserve
reserve 应该根据实际需要使用,过度预分配会浪费内存。
实例
#include <iostream>
<vector>
int main() {
// 错误的做法:过度预分配
std::vector<int> v1;
v1.reserve(1000000); // 只需要 10 个元素,却预分配了 100 万的空间!
for(int i = 0; i < 10; ++i) {
v1.push_back(i);
}
std::cout << "只需要 10 个元素 - size: " << v1.size()
<< ", capacity: " << v1.capacity() << std::endl;
// 正确的做法:按需预分配
std::vector<int> v2;
v2.reserve(10);
for(int i = 0; i < 10; ++i) {
v2.push_back(i);
}
std::cout << "需要 10 个元素 - size: " << v2.size()
<< ", capacity: " << v2.capacity() << std::endl;
return 0;
}
<vector>
int main() {
// 错误的做法:过度预分配
std::vector<int> v1;
v1.reserve(1000000); // 只需要 10 个元素,却预分配了 100 万的空间!
for(int i = 0; i < 10; ++i) {
v1.push_back(i);
}
std::cout << "只需要 10 个元素 - size: " << v1.size()
<< ", capacity: " << v1.capacity() << std::endl;
// 正确的做法:按需预分配
std::vector<int> v2;
v2.reserve(10);
for(int i = 0; i < 10; ++i) {
v2.push_back(i);
}
std::cout << "需要 10 个元素 - size: " << v2.size()
<< ", capacity: " << v2.capacity() << std::endl;
return 0;
}
代码解析:
- 过度预分配会浪费内存空间。
- 应该根据实际需要的元素数量来设置
reserve的参数。
示例 5:reserve 与容量检查
可以在添加元素前检查容量是否足够。
实例
#include <iostream>
#include <vector>
void addElements(std::vector<int>& v, int count) {
// 如果当前容量不够,预留足够的空间
if(v.capacity() < v.size() + count) {
v.reserve(v.size() + count);
}
// 添加元素
for(int i = 0; i < count; ++i) {
v.push_back(v.size());
}
}
int main() {
std::vector<int> data;
std::cout << "初始 - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
addElements(data, 50);
std::cout << "添加 50 个后 - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
addElements(data, 50);
std::cout << "再添加 50 个后 - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
return 0;
}
#include <vector>
void addElements(std::vector<int>& v, int count) {
// 如果当前容量不够,预留足够的空间
if(v.capacity() < v.size() + count) {
v.reserve(v.size() + count);
}
// 添加元素
for(int i = 0; i < count; ++i) {
v.push_back(v.size());
}
}
int main() {
std::vector<int> data;
std::cout << "初始 - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
addElements(data, 50);
std::cout << "添加 50 个后 - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
addElements(data, 50);
std::cout << "再添加 50 个后 - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
return 0;
}
代码解析:
- 可以在函数中动态检查并预留容量。
- 这确保了添加元素时不会发生内存重新分配。

C++ 容器类 <vector>