vector,动态数组,类似数组,可以动态分配内存。
内存实现
类似string,为一段连续空间。有已使用空间和 目前可用空间这个概念。
- start : 已使用空间的开头
- finish : 已使用空间的结尾
- end_of_storage : 目前可用空间结尾
空间不够时,会自动分配新空间,然后将旧地址内容拷贝到新地址上。 新分配空间大小增长规则为:
linux下为上一次的2倍,windows为上一次的1.5倍。
关于空间分配有一个点注意: 涉及到新内存分配时,特别注意旧的迭代器会失效!
操作
根据start,finish ,end_of_storage就可以轻松获取的操作
- begin : return start,返回迭代器
- end : return finish,返回迭代器
- size : 返回当前已占空间大小
- capcity : 返回可使用空间容量
- empty : 判断非空
- front : 第一个元素
- back : 最后一个元素
- operator[] : *(begin()+n)
- at : 类似opeator[]
其他操作:(注:下面iter,first,last全部为迭代器,begin/end为上面描述开头结尾迭代器)
- push_back : 结尾插入元素
- pop_back : 结尾弹出元素
- erase(iter) : 删除某个位置元素
- erase(first,last) : 删除[first,last)内所有元素
- clear : 即erase(start,finish)
- insert(iter,size,n) : 在iter之前插入size个元素,元素内容为n,返回值为插入的第一元素的新迭代器
- insert(iter,n): 在iter之前插入元素n
关于insert操作有一点注意,插入之后iter及其之后的迭代器失效(因为规定vector只要在某个迭代器前面插入元素,这个迭代器就会失效。 标准没有规定使用失效的迭代器应该如何处理。)如果要使用,可使用新迭代器接受返回值.
vector<int> v;
v.push_back(1);
v.push_back(2);
vector<int>::iterator iter = v.begin();
v.insert(iter, 3);
v.insert(iter, 4); //报错,进行insert操作后iter及其之后的迭代器都不可使用
iter = v.insert(iter, 3);
v.insert(iter, 4); //正确,使用iter接收新的迭代器
- resize: 调整容器的长度大小,使其能容纳n个元素。如果n小于容器的当前的size,则删除多出来的元素
reserver : 预分配空间为n的容器,已知要插入的元素个数时,为避免不断push_back引起的不断拷贝新空间操作,可预先分配容器大小
swap: 顾名思义,交换两个容器或元素。 其中一种巧妙的用法是常用来清空vector所占的空间。
我们知道,vector进行clear操作后,相当于执行erase(start,finish),查看源码可知只是析构了内部所有元素,并没有释放vector所占的空间。可用下例验证。
vector<int> v;
for (int i = 0; i < 100; ++i)
{
v.push_back(i);
}
cout << v.capacity() << endl;
v.clear();
cout << v.capacity() << endl; //查看结果可知,和上面输出一致.
这里可以巧妙的应用swap来释放vector所占用的空间。swap交换技巧实现内存释放思想:vector()使用vector的默认构造函数建立临时vector对象,再在该临时对象上调用swap成员,swap调用之后对象myvector占用的空间就等于一个默认构造的对象的大小,临时对象就具有原来对象v的大小,而该临时对象随即就会被析构,从而其占用的空间也被释放。
vector<int> v;
for (int i = 0; i < 100; ++i)
{
v.push_back(i);
}
vector<int> tmp;
tmp.swap(v);
vector<int>().swap(v); //简写