zoukankan      html  css  js  c++  java
  • 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才会自动释放缓冲区。

    拓展阅读

    vector迭代器失效解决方法 及 内存原理

    C++中STL中vector和list的迭代器失效问题

  • 相关阅读:
    edge.js架起node.js和.net互操作桥梁
    Swift学习:闭包(Closures)
    swift UIAlertController教程
    linux配置IP的方法
    centos 6.5安装vncserver 并开启远程桌面
    CSS中各种居中方法
    jquery中的index方法和eq方法
    line-height的用法(一)
    第八章—BOM(一)
    第四章—变量,作用域和内存问题(一)
  • 原文地址:https://www.cnblogs.com/noticeable/p/14861852.html
Copyright © 2011-2022 走看看