程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實戰c++中的vector系列--可怕的迭代器失效(vector重新申請內存)

實戰c++中的vector系列--可怕的迭代器失效(vector重新申請內存)

編輯:C++入門知識

實戰c++中的vector系列--可怕的迭代器失效(vector重新申請內存)


vector給我們提供了很多的方便,但是偶爾也會有陷阱。當不注意的時候,就掉入其中。說到底,還是對vector的機制不夠徹底掌握。

很輕松的寫下這段代碼:

#include
#include
using namespace std;
int main()
{
    vector v;
    v.push_back(1);

    std::vector::iterator iter1 = v.begin();
    v.push_back(1);

    int n = *iter1;//shit
    cout << n << endl;
    return 0;

}

上面的代碼運行時崩潰,就是因為迭代器iter1在vector push_back新值後失效了。切記!
但是為什麼會失效?
如果我先預先resize足夠大,那麼會如何呢?

#include
#include
using namespace std;
int main()
{
    vector v;
    v.resize(4);
    v.push_back(1);

    std::vector::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
#include
using namespace std;
int main()
{
    vector v;
    v.reserve(2);
    v.push_back(0);

    std::vector::iterator iter1 = v.begin();
    v.push_back(1);
    int n = *iter1;
    cout << n << endl;
    return 0;

}

還是以push_back兩個元素為例,reserve(1)還是會導致崩潰,還是造成迭代器的失效。

接下來的問題就是vector的內存機制,當容量不夠時,會申請多少內存?
還是寫個程序看看:

#include
#include
using namespace std;
int main()
{
    vector 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才會自動釋放緩沖區。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved