对于这道问题在每年的面试中都会提到,出现频率之高都已经到了令人发指的地步,所以在此做一总结。对于这部分知识据说《effective STL》中有详细介绍与代码实现。
参考:《C++ primer》以及相关网络资源。
1.vector容器的自增长
vector中所有元素都是以连续的方式进行存储,原理就和数组一样每个元素相互紧挨着存储,但是当我们需要往其中insert元素时将会发生什么情况呢?
如果容器已经没有空间容纳新插入的元素,此时,由于vector中的元素是连续存放,所以不能随便找个地方存放,于是vector会重新分配一块大的内存,将原来的数据拷贝过来再将原来的空间释放掉,而这部分内存一般情况下比需要存储的数据所需要的内存大,这样当再有元素需要存储时就不需要在开辟内存了。其中vector中有capacity和size这两个接口,capacity指的就是容器的实际容量,超过这一个容量就需要在此分配内存,size指的就是实际存储的内存(当然我们可以通过reserve来给我们的vector自定义capacity以减少开辟内存的)。
2,内存释放
对于内存的释放,vector没有提供任何接口,即使使用clear与erase。clear只是清空原来的数据内存不会有任何改动,erase如果删除的是中间的元素,只是简单的将后面的元素前移(好像是网易的面试题)也不会对内存有任何影响。对此我参考了网络上部分信息。提供的方法就是通过swap函数。
#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int j;
vector<int> v;
for(j =0; j < 25; j++)
v.push_back(j);
cout<<"the vector size is: "<<v.size()<<endl;
cout<<"the vector capacity is:"<<v.capacity()<<endl;
v.reserve(50);
cout<<"after reverse the vector capacity is "<<v.capacity()<<endl;
cout<<"...............clear......................"<<endl;
v.clear();
cout<<"the vector size is: "<<v.size()<<endl;
cout<<"the vector capacity is:"<<v.capacity()<<endl;
cout<<"......................................."<<endl;
vector<int>().swap(v); //交换
cout<<"the vector size is: "<<v.size()<<endl;
cout<<"the vector capacity is:"<<v.capacity()<<endl;
}
现在 我们来解释一下上述红色部分为什么能够释放内存,我们先来看一下下面的代码:
#include<iostream>
#include<vector>
using namespace std;
class A
{
public:
A(){cout<< "construct A"<<endl;}
~A(){cout<<"destruct A"<<endl;}
};
int main()
{
A();
while(1);
return 0;
}
A()这句话的输出为construct A和destruct A;也就是说我们构造了一个临时A对象最后又将它析构掉了;上述红色vector<int>()也是构造了一个临时vector对象,但是该对象调用完swap后自动调用析构函数将其析构掉了,所以当我们交换后也就能够自动释放内存。感觉这个和我翻译的那篇《copy-and-swap》那篇文章的原理很像,都是构造一个临时变量用完后自动调用析构函数将其释放掉。