文章目录
一、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 );
参数介绍:
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中的所有元素将会拷贝到这个更大的新空间里,这时所有迭代器将会失效。为什么会失效?
以下是证明:
void test5_2(vector<int>& v) { 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 ; }
那如何处理迭代器失效呢?其实再给迭代器赋值一次
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()
为好。
最后,如果有误,烦请各位指出!!