一、vector容器成员函数——reserve()
2.实用意义:
vecotr容器中不断的push_back(), 会进行多次内存再分配行为,为了减少内存再分配的次数,下面有请reserve()函数出场!!!
3.功能:
增加vector容器容量 c a p a c i t y capacity capacity
4.使用方法
函数原型:
void reserve( size_type new_cap );
参数介绍:
new_cap:vector的新容量
5.例子
- 5.1 结论:
reserve()不改变vector的大小 s i z e size size,改变vector的容量 c a p a c i t y capacity capacity,以下是证明:
int foo()
{
vector<int> v{ 1, 3, 5, 7, 9 };
cout << v.size() << endl; // 5
cout << v.capacity() << endl; // 5
v.reserve(10); // (1) 改变vector的什么呢?
cout << "After reserve(): " << endl;
cout << v.size() << endl; // 5,看!不改变vector的元素个数
cout << v.capacity() << endl; // 10,改变了vector的容量!
return 0;
}
-
5.2 结论:
reserve(new_cap),当new_cap大于vector原本的容量时,迭代器会失效!!当要新容量大于vector原本的容量时,vector会找一个更大的空间,然后vector中的所有元素将会拷贝到这个更大的新空间里,这时所有迭代器将会失效。为什么会失效?
因为迭代器也是一个指针,它指向的是过去分配的存储空间,当vector元素搬家后,而迭代器仍指向旧的家的存储单元。
以下是证明:
void test5_2(vector<int>& v) //capacity为 5 { vector<int>::iterator iter = v.begin(); for (;iter != v.end(); ++iter) cout << *iter << " "; // 1, 3, 5, 7, 9 cout << endl; v.reserve(10); for (;iter != v.end(); ++iter) cout << *iter << " "; // 一堆随机数 cout << endl; return ; }下面输出的第一行是调用
reserve()之前,通过迭代器正常输出的vector元素;
那如何处理迭代器失效呢?其实再给迭代器赋值一次
v.begin()就好辣!void test5_2(vector<int>& v) { vector<int>::iterator iter = v.begin(); for (;iter != v.end(); ++iter) cout << *iter << " "; cout << endl; v.reserve(10); iter = v.begin(); // 就看这一行!!!,比上面代码就多了这一句 for (;iter != v.end(); ++iter) cout << *iter << " "; cout << endl; return ; }聪明的你一定早就知道方法啦,还是看一下输出吧:
1 3 5 7 9 1 3 5 7 9这下迭代器就没事啦!
到这里一定很好奇,如果
reserve(new_cap)中的new_cap小于vector原本的容量,那将会怎么样?测试结论是没有任何效果,所以还是安安分分使用
reserve()作为vector扩容的方法吧,如果需要缩小vector容量,可以使用shrink_to_fit()。测试证明:
void test5_1(vector<int>& v) { cout << v.size() << endl; // 5 cout << v.capacity() << endl; // 5 v.reserve(8); cout << "After reserve(8): " << endl; cout << v.size() << endl; // 5 cout << v.capacity() << endl; // 8,不出预料变8了 v.reserve(3); // 我缩!! cout << v.size() << endl; // 5 cout << v.capacity() << endl; // 8,没有起任何效果 return ; }
6.注意
- 正确使用reserve可以避免不必要的内存再分配,例如,未初始化的vector变量v1,如果多次进行
push_back()操作,必然会有多次内存再分配的操作。如果在push_back()之前使用reserve进行一次合理的扩容,那就会提高性能。 - 当vector按引用传递给函数作参数时,如果不知道该vector的使用特征,还是不要使用
reserve()为好。
来源:cppreference注意事项
Correctly using
reserve()can prevent unnecessary reallocations, but inappropriate uses ofreserve()(for instance, calling it before every push_back() call) may actually increase the number of reallocations (by causing the capacity to grow linearly rather than exponentially) and result in increased computational complexity and decreased performance. For example, a function that receives an arbitrary vector by reference and appends elements to it should usually not callreserve()on the vector, since it does not know of the vector’s usage characteristics.When inserting a range, the range version of insert() is generally preferable as it preserves the correct capacity growth behavior, unlike
reserve()followed by a series of push_back()s.
reserve()cannot be used to reduce the capacity of the container; to that end shrink_to_fit() is provided.
最后,如果有误,烦请各位指出!!
本文详细介绍了C++中vector容器的reserve()函数,其主要作用是预分配内存以减少内存再分配次数。当reserve()设置的新容量大于原有容量时,会导致迭代器失效,因为元素会被拷贝到新的内存空间。解决办法是在使用前重新赋值迭代器。同时,如果reserve()设置的新容量小于现有容量,则不会产生任何效果。正确使用reserve()可以优化性能,但不确定vector使用特征时应谨慎使用。

5万+

被折叠的 条评论
为什么被折叠?



