可怕的迭代器失效(vector重新申请内存)

实战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才会自动释放缓冲区。

文章导航