vector学习记录
首先如上图所示左边是vector的内存布局,右边是源代码,vector中的protect成员中有三根指针start,finish,end_of_storage,分别指向vector的第一个元素的首地址,最后一个元素的下一个元素的首地址,以及vector边界尾部的地址,然后下面是vector中一些公有函数,都比较简单,下面主要介绍vector是如何扩容的,vector要扩容肯定是插入元素时容量不够,这里插入有两种方法,分别是insert和push_back
上面是push_back的一些源码,首先当finish与end_of_storage指向的位置相等时就说明这时vector的空间被用完,然后就调用insert_aux函数,然后用old_size * 2当成新的vector的len,然后调用分配器去分配内存,然后将老的vector里面的内容拷贝到新的vector中,当该函数被insert调用时就要执行,现将插入点之前的内容拷贝到新的vector中然后插入新的元素然后再将插入点之后的元素拷贝到新的vector中,这个拷贝的过程中涉及到大量的拷贝构造函数的调用和析构函数的调用所以时间消耗比较大,如果元素中函数指针一定要在析构函数中delete掉,要不然会内存泄漏,拷贝构造函数一定要注意是深拷贝还是浅拷贝。vector比较简单,和课堂上学习的线性很像。
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vector<int>::iterator it = vec.begin();
it = vec.erase(it);
cout << *it << endl;
}
这里是对vector中erase()函数的探究,erase()函数需要传入一个迭代器,然后删除迭代器所指向的元素然后将该元素后面的元素前移,返回下一个位置的迭代器,当然这样会很消耗时间,所以如果经常需要删除元素就需要使用list双向循环链表了。
#include <vector>
#include <iostream>
using namespace std;
class Test
{
public:
Test(string s)
{
str = s;
cout<<"Test creat\n";
}
~Test()
{
cout<<"Test delete:"<<str<<endl;
}
string& getStr()
{
return str;
}
void setStr(string s)
{
str = s;
}
void print()
{
cout<<str<<endl;
}
private:
string str;
};
int main()
{
vector<Test*> vec;
Test* test1 = new Test("11");
Test* test2 = new Test("22");
Test* test3 = new Test("33");
vec.push_back(test1);
vec.push_back(test2);
vec.push_back(test3);
vector<Test*>::iterator it = vec.begin();
it = vec.erase(it);
(*it)->print();
}
通过上面的测试可以看见,vector中存放的是指针的时候,删除vector中的指针时,指针所指向的空间的内存是没有释放的。所以最好不要这样做。
这篇文章是学完侯捷老师的视频所写,如有错误希望指正。