vector底层是一个动态数组,包含三个迭代器,start和finish之间是已经使用的空间范围,end_of_storage是整块连续空间包括备用空间的尾部。
vector内存增长机制:当空间不够装下数据时,会自动申请另一片更大的空间,大小为原来的两倍,然后把原来的数据拷贝到新的内存空间,接着释放原来的空间。
当删除数据的时候,存储空间不释放,只是清空里面的数据。
因此,对vector的操作一旦引擎了空间的重新配置,指向原vector的所有迭代器都失效。
(2)vector中的reserve和resize的区别
vector中reserve和resize的区别:
reserve是直接扩充到已经确定的大小,减少多次开启、释放空间。
resize()可以改变空间的大小,也有改变默认值的功能,capacity的大小也会随着改变。
(3)vector中的size和capacity的区别
size表示当前vector中有多少个元素(finish - start),而capacity函数则表示它已经分配的内存中可以容纳多少元素(end_of_storage - start)。
(4)vector的元素类型可以是引用吗?
vector的底层实现要求连续的对象排列,引用并非对象,没有实际地址,因此vector的元素类型不能是引用。
(5)vector迭代器失效的情况
当插入一个元素到vector中,由于引起了内存重新分配,所以指向原内存的迭代器全部失效。
当删除容器中一个元素后,该迭代器所指向的元素已经被删除,那么也造成迭代器失效。erase方法会返回下一个有效的迭代器,所以当我们要删除某个元素时,需要it=vec.erase(it);。
(6)正确释放vector的内存(clear(), swap(), shrink_to_fit())
vec.clear():清空内容,但是不释放内存。
vector().swap(vec):清空内容,且释放内存,相当于得到一个全新的vector。
vec.shrink_to_fit():请求容器降低其capacity和size匹配。
vec.clear();vec.shrink_to_fit();:清空内容,且释放内存。
实践代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template<typename T>
void coutall(vector<T> &vct)
{
//使用auto,请确保编译器支持C++11
for(auto it = vct.begin();it != vct.end();it++)
{
cout<< *it << " ";
}
cout <<endl;
}
int main() {
cout << "STL VECTOR TEST START!\n";
//初始化
vector<int> vec_name1;
vector<int> vec_name2(vec_name1);
vector<int> vec_name3(100,1);
vector<int> vec_name4(100);//默认值会是0
//C++标准11,可用数组对vector赋初值初始化
vector<int> vec_name5{1,2,3,4};
int arr[]={0,1,2,3,4};
vector<int> vec_name6(begin(arr),end(arr));
char arr2[]="abcde";
vector<char> vec_name7(begin(arr2),end(arr2));
//使用迭代器遍历,最上面也有封装遍历打印函数
vector<int>::iterator it;
for( it=vec_name3.begin();it!=vec_name3.end();++it)
{
cout<<*it<<" ";
}
coutall(vec_name7);
//设置空间大小 reserve 和resize 查看元素个数和空间大小
vec_name3.reserve(200);
vec_name4.resize(200,1);
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
cout<<"vec_name4.size ="<<vec_name4.size()<<endl;
cout<<"vec_name4.capacity ="<<vec_name4.capacity()<<endl;
vec_name3.reserve(150);//该语句的修改不会生效,也不会报错,因为150小于当前capacity200
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
//判断是否为空
cout<<"vec_name1.empty = "<<vec_name1.empty()<<endl;
cout<<"尾部添加元素 pop_back()"<<endl;
vec_name3.push_back(4);
vec_name3.push_back(5);
coutall(vec_name3);
cout<<"尾部删除元素 pop_back()"<<endl;
vec_name3.pop_back();
coutall(vec_name3);
//任意位置插入元素 insert函数
vec_name3.insert(vec_name3.begin()+1,10); //第一个元素前插入元素,值为10
vec_name3.insert(vec_name3.begin()+1,10); //第一个元素前插入元素,值为10
//删除指定元素
vec_name3.erase(vec_name3.begin()+1); //删除第1个元素
vec_name3.erase(vec_name3.end()-1); //删除最后一个元素
vec_name3.erase(vec_name3.begin()+2,vec_name3.end()-2); //删除区间[i,j];
coutall(vec_name3);
//注意:关于vector的下标操作。vector的下标操作只能改变或者获取已有的元素的值,不能往vector里添加元素!
//使用下标改变元素的值和获取,但是此方法不会判断是否越界,因此尽量使用迭代器或者at(),
vec_name3[0] = 20;
for(int i=0;i<vec_name3.size();i++)
{
cout<<vec_name3[i]<<" ";
}
cout<<endl<<vec_name3.at(1)<<endl;
cout<<"返回第一个元素 front"<<endl;
cout<<vec_name3.front()<<endl;
cout<<"返回最后一个元素 back"<<endl;
cout<<vec_name3.back()<<endl;
//常用函数,元素排序
sort(vec_name3.begin(),vec_name3.end());
coutall(vec_name3);
//元素查找,find(),求迭代器之间的距离 distance()
vector<int>::iterator result = find(vec_name3.begin(),vec_name3.end(),10);
if(result == vec_name3.end())
{
cout << "没找到"<<endl;
}
else
{
cout << "存在此元素,元素位数为"<<distance(vec_name3.begin(),result)<<endl;
}
//反转容器
reverse(vec_name3.begin(),vec_name3.end());
coutall(vec_name3);
//交换元素或交换容器,交换容器是整个容器的元素,可用空间全部交换。
swap(vec_name3[0],vec_name3[1]);
coutall(vec_name3);
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
coutall(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
swap(vec_name3,vec_name6);
cout<<"-------after swap-----"<<endl;
coutall(vec_name3);
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
coutall(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
//清除容器 clear只是清除元素,但是空间没有释放。
vec_name6.clear();
coutall(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
cout<<"第一种方式,定义一个空容器,和之前容器swap,那么原本有数据有空间的容器就清空了。"<<endl;
vector<int>().swap(vec_name6);
cout<<"vec_name6.size ="<<vec_name6.size()<<endl;
cout<<"vec_name6.capacity ="<<vec_name6.capacity()<<endl;
cout<<"第二种方式,先clear,再使用shrink_to_fit()"<<endl;
coutall(vec_name3);
vec_name3.clear();
vec_name3.shrink_to_fit();
cout<<"vec_name3.size ="<<vec_name3.size()<<endl;
cout<<"vec_name3.capacity ="<<vec_name3.capacity()<<endl;
cout<<endl<<"STL VECTOR TEST END!\n";
return 0;
}