可怕的迭代器失效(vector重新申请内存)
最后更新于:2022-04-01 06:44:05
##实战c++中的vector系列--可怕的迭代器失效(vector重新申请内存)
vector给我们提供了很多的方便,但是偶尔也会有陷阱。当不注意的时候,就掉入其中。说到底,还是对vector的机制不够彻底掌握。
很轻松的写下这段代码:
~~~
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
v.push_back(1);
std::vector<int>::iterator iter1 = v.begin();
v.push_back(1);
int n = *iter1;//shit
cout << n << endl;
return 0;
}
~~~
上面的代码运行时崩溃,就是因为迭代器iter1在vector push_back新值后失效了。切记!
但是为什么会失效?
如果我先预先resize足够大,那么会如何呢?
~~~
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
v.resize(4);
v.push_back(1);
std::vector<int>::iterator iter1 = v.begin();
v.push_back(1);
int n = *iter1;
cout << n << endl;
return 0;
}
~~~
上面的代码正常运行,因为之前resize了足够的空间,即迭代器不会失效。
我们就已给vector push_back两个元素为例。resize(1), resize(2), resize(3)程序还是会崩溃。还是容量不足,导致vector重新分配内存,而导致迭代器失效。
之前讲过了resize与reserve的区别,那么上面的代码如果使用reserve呢?
~~~
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
v.reserve(2);
v.push_back(0);
std::vector<int>::iterator iter1 = v.begin();
v.push_back(1);
int n = *iter1;
cout << n << endl;
return 0;
}
~~~
还是以push_back两个元素为例,reserve(1)还是会导致崩溃,还是造成迭代器的失效。
接下来的问题就是vector的内存机制,当容量不够时,会申请多少内存?
还是写个程序看看:
~~~
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> v;
for (int i = 1; i < 100; i++)
{
cout << "capacity:" << v.capacity() << ", " << "size" << v.size() << endl;
v.push_back(i);
}
return 0;
}
//输出:
capacity:0, size0
capacity:1, size1
capacity:2, size2
capacity:3, size3
capacity:4, size4
capacity:6, size5
capacity:6, size6
capacity:9, size7
capacity:9, size8
capacity:9, size9
capacity:13, size10
capacity:13, size11
capacity:13, size12
capacity:13, size13
capacity:19, size14
capacity:19, size15
capacity:19, size16
capacity:19, size17
capacity:19, size18
capacity:19, size19
capacity:28, size20
capacity:28, size21
capacity:28, size22
capacity:28, size23
capacity:28, size24
capacity:28, size25
capacity:28, size26
capacity:28, size27
capacity:28, size28
capacity:42, size29
capacity:42, size30
capacity:42, size31
capacity:42, size32
capacity:42, size33
capacity:42, size34
capacity:42, size35
capacity:42, size36
capacity:42, size37
capacity:42, size38
capacity:42, size39
capacity:42, size40
capacity:42, size41
capacity:42, size42
capacity:63, size43
capacity:63, size44
capacity:63, size45
capacity:63, size46
capacity:63, size47
capacity:63, size48
capacity:63, size49
capacity:63, size50
capacity:63, size51
capacity:63, size52
capacity:63, size53
capacity:63, size54
capacity:63, size55
capacity:63, size56
capacity:63, size57
capacity:63, size58
capacity:63, size59
capacity:63, size60
capacity:63, size61
capacity:63, size62
capacity:63, size63
capacity:94, size64
capacity:94, size65
capacity:94, size66
capacity:94, size67
capacity:94, size68
capacity:94, size69
capacity:94, size70
capacity:94, size71
capacity:94, size72
capacity:94, size73
capacity:94, size74
capacity:94, size75
capacity:94, size76
capacity:94, size77
capacity:94, size78
capacity:94, size79
capacity:94, size80
capacity:94, size81
capacity:94, size82
capacity:94, size83
capacity:94, size84
capacity:94, size85
capacity:94, size86
capacity:94, size87
capacity:94, size88
capacity:94, size89
capacity:94, size90
capacity:94, size91
capacity:94, size92
capacity:94, size93
capacity:94, size94
capacity:141, size95
capacity:141, size96
capacity:141, size97
capacity:141, size98
~~~
选几个数据分析一下:
0-1-2-3-4-6-9-13-19-28-42-63-94-141
从第二项开始:
2/2+2=3
3/2+3=4
4/2+4=6
6/2+6=9
9/2+9=13
13/2+13=19
19/2+19=28
28/2+28=42
42/2+42=63
63/2+63=94
94/2+94=141
**每次扩容50%**
删除容器中数据的时候,缓冲区大小并不会改变,仅仅只是清楚了其中的数据,只有在析构函数调用的时候vector才会自动释放缓冲区。