vector底层结构:动态类型的顺序表
既然是顺序表,那么就什么类型都可以存放,那么也就是可以存放字符类型,那么为什么又要有string类型呢?
其实这个就是字符数组和字符串的区别?
字符数组不一定是字符串,因为字符串一定有’\0’,其次就是刚初始化好的vector类里面就是空的,什么都没有,而定义好的string空类,里面就有16个字节的空间,其中第一个自己存放的是’\0’,所以有效空间就是15个,随着插入元素’\0’后移。
打印结果:
打印结果就是,数组的’\0’也即是空格
打印结果:编译通过运行出错
vector<int> v1;
vector<int> v2(10,5);
vector<int> v3(v2);
int array[10] = {1,2,3,4,5,67,8,9,0};
vector<int> v4(array,array+(sizeof(array)/sizeof(array[0])); //区间构造
vector<int> v5 {1,2,3,4,5,6,4};
注意使用vector里面的erase的时候的注意事项,如何删除最后一个元素
库函数find()返回的是迭代器
使用vector(定义二维数组)
vector的增容机制:
空的vector的size和capacity就是0
我试过,连续插入一百个元素,并且在容量增大时打印出容量大小1,2,3,4,6,9,13,19,28,42,63,94,141,
VS下的vector的扩容机制大概是1.5倍,而在Linux下是2倍(SGI版本的STL)
在使用vector的时候需要注意,vector和我们通常使用的整型数组还是有区别的:
int a[10] = {}; //其实在数组定义好之后,里面就是有小元素就是有内容的,只不过是全为0
cout << a[0] << endl; //要是打印的话还是可以打印出来的
但是vector不一样,咋们首先不说vector定义一个空类之后,空类的有效元素是0,容量也是0,
就算你使用reserve()函数在底层把空间扩大,此时你再访问[0]号位置的元素,他还是会报你内存访问越界,因为你并没
有插入元素,此时的容器内部只是空间扩大,但是有效元素的个数还是0,也就是说在使用vector容器的时候,访问的下标
大于或者等于有效元素的个数,就会内存访问越界,out of range
但是你要是使用resize()来扩容就不一样了,虽然它改变的是有效元素的个数,但是当改变的个数大于现在的容量的时
候,他还是会扩容的,而且在用户不提供填充内容的情况下,他会填充0,也就是说使用resize()来扩容,底层的有效元
素个数也会跟着改变(两个函数的区别在之前的文章中我已经讲过)
迭代器失效:
因为迭代器的本质就是指针,迭代器失效指的就是,指针指向了非法的空间
vector<int> v{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
auto it = v.begin();
v.push_back(100);
while (it != v.end())
cout << *it << " ";
知道迭代器失效的原因之后,是因为扩容,所以我们可以在使用前就先进行一步扩容操作v.reserve(n);就可以了,也可以给迭代器重新赋值就可以了。
使用push_back()可能会引起扩容,扩容函数封装在push_back()函数里面了
清空vector中的所有元素的操作:
resize()改变有效元素的个数
clear()清空有效元素
erase()按照次函数给出的迭代器进行区间删除
但是erase()这个函数还给出了一个iterator erase ( iterator position );函数
但是会爆出如上的错误,其实这个也是一种迭代器失效,当你删除这个位置的元素之后,当前位置的指针指向的就是一块非法的内存,此时在对指针进行++操作就是非法的就类似于下面这段代码
说我使用了为初始化的a
那么该如何解决上述的问题呢?
iterator erase ( iterator position );发现此函数的返回值,也是一个迭代器,而且返回的是删除位置的下一个元素的迭代器
vector:迭代器失效的场景
push_back---- - 可以会自动扩容
resize(), reserve(), insert(), assign()
使用esear()的时候也容易引起迭代器失效
所以测了一下引用也会失效