• vector的内存分配机制分析


    该程序初步演示了我对vector在分配内存的时候的理解。可能有误差,随着理解的改变,改代码可以被修改。

      1 /*
      2 功能说明:
      3     vector的内存分配机制分析。
      4 代码说明:
      5     vector所管理的内存地址是连续的。程序在不断的push_back的过程中,如果当前所管理的内存不能装下新的元素的时候,程序会创建更大的地址连续的空间来保存更多的元素。
      6     这种机制会引起大量的无用的复制和删除操作。如果vector的元素为类结构的时候,他就会有很多临时变量产生。通过复制构造函数和析构函数,可以看到这些操作。
      7 实现方式:
      8     
      9 限制条件或者存在的问题:
     10  11 */
     12 #include <iostream>
     13 #include <string>
     14 #include <vector>
     15 
     16 #include <windows.h>
     17 
     18 using namespace std;
     19 
     20 class CData
     21 {
     22 public:
     23     CData()
     24     {
     25         sequence = 0;
     26         this->remark = "default string";
     27 
     28         cout << "CData()	" << toString() <<"	"<< this << endl;
     29     }
     30 
     31     CData(int i,string &s)
     32     {
     33         this->sequence = i;
     34         this->remark = s;
     35 
     36         cout << "CData(int i,string &s)	" << toString() << "	" << this << endl;
     37     }
     38 
     39     CData(const CData &data)
     40     {
     41         this->sequence = data.sequence;
     42         this->remark = data.remark;
     43 
     44         cout << "CData(const CData &data)	" << toString() << "	" << this << endl;
     45     }
     46 
     47     CData operator = (const CData &data)
     48     {
     49         this->sequence = data.sequence;
     50         this->remark = data.remark;
     51 
     52         cout << "CData operator = (const CData &data)	" << toString() << "	" << this << endl;
     53 
     54         return *this;
     55     }
     56 
     57     void setSequence(const int i)
     58     {
     59         this->sequence = i;
     60     }
     61 
     62     void setRemark(const string &s)
     63     {
     64         this->remark = s;
     65     }
     66 
     67     string toString() const
     68     {
     69         char tmp[2048] = { 0 };
     70         sprintf(tmp, "[sequence:%d | remark:%s]", this->sequence, this->remark.c_str());
     71 
     72         //此处应该有内存复制操作,所以不用担心返回后tmp数组所指向的内存被修改或者不存在的情况。
     73         return tmp;
     74     }
     75 
     76     ~CData()
     77     {
     78         cout << "~CData()	" << this << endl;
     79     }
     80 protected:
     81 private:
     82     int sequence;
     83     string remark;
     84 };
     85 
     86 int main(int argc, char **argv)
     87 {
     88     cout << "process begin at " << (void*)&main << endl;
     89 
     90     string str = "baby_test";
     91     CData data1(1, str);
     92     CData data2(2, str);
     93     CData data3(3, str);
     94     CData data4(4, str);
     95     CData data5(5, str);
     96     CData data6(6, str);
     97     CData data7(7, str);
     98     CData data8(8, str);
     99     CData data9(9, str);
    100     CData data10(10, str);
    101 
    102     cout << "push CData to vector" << endl;
    103     vector<CData> vec_data;
    104     cout << "max size of vector<CData> is " << vec_data.max_size() << endl;
    105     cout << "size of vector<CData> is " << vec_data.size() << endl;
    106     
    107     cout << "****************vec_data.push_back(data1)" << endl;
    108     vec_data.push_back(data1);
    109     Sleep(2 * vec_data.size());
    110     
    111     cout << "****************vec_data.push_back(data2)" << endl;
    112     vec_data.push_back(data2);
    113     Sleep(2 * vec_data.size());
    114     
    115     cout << "****************vec_data.push_back(data3)" << endl;
    116     vec_data.push_back(data3);
    117     Sleep(2 * vec_data.size());
    118 
    119     cout << "****************vec_data.push_back(data4)" << endl;
    120     vec_data.push_back(data4);
    121     Sleep(2 * vec_data.size());
    122 
    123     cout << "****************vec_data.push_back(data5)" << endl;
    124     vec_data.push_back(data5);
    125     Sleep(2 * vec_data.size());
    126 
    127     cout << "****************vec_data.push_back(data6)" << endl;
    128     vec_data.push_back(data6);
    129     Sleep(2 * vec_data.size());
    130 
    131     cout << "****************vec_data.push_back(data7)" << endl;
    132     vec_data.push_back(data7);
    133     Sleep(2 * vec_data.size());
    134 
    135     cout << "****************vec_data.push_back(data8)" << endl;
    136     vec_data.push_back(data8);
    137     Sleep(2 * vec_data.size());
    138 
    139     cout << "****************vec_data.push_back(data9)" << endl;
    140     vec_data.push_back(data9);
    141     Sleep(2 * vec_data.size());
    142 
    143     cout << "****************vec_data.push_back(data10)" << endl;
    144     vec_data.push_back(data10);
    145     Sleep(2 * vec_data.size());
    146 
    147     // 程序到此为止,日志显示的比较怪异。
    148     // 具体来说,就是,将CData对象push到向量中的时候,程序会通过复制构造函数,创建一些临时变量。
    149     // 创建临时变量的原因分析:这可能与vector的内存分配方式有关。vector所创建的对象的内存的地址是连续的。
    150     // 当当前的vector所拥有内存不能装入新的元素的时候,程序会创建开辟新的地址连续的空间,并将原来地址中的元素全部复制一份,保存到新的地址中。然后在删除原来的地址中的对象。
    151 
    152     cout << "===============show vector by iterator" << endl;
    153     for (vector<CData>::iterator itr = vec_data.begin(); itr != vec_data.end(); itr++)
    154     {
    155         // 显示的地址信息,是最后一次push的时候所复制的对象的地址。
    156         cout << "address of itr is " << &(*itr) << "	value is " << itr->toString() << endl;
    157     }
    158 
    159     cout << "===============clear vector 1" << endl;
    160     // vector中的元素不是指针,此处的清理,会调用析构函数。
    161     vec_data.clear();
    162 
    163     // 根据上面的分析,再次测试。
    164     // 本次测试是在将元素push到vector中之前,先为vector申请“足够大”的内存。
    165     vec_data.reserve(20);
    166     cout << "size of vector<CData> is " << vec_data.size() << endl;
    167     cout << "capacity of vector<CData> is " << vec_data.capacity() << endl;
    168 
    169     cout << "****************vec_data.push_back(data1)" << endl;
    170     vec_data.push_back(data1);
    171     Sleep(2 * vec_data.size());
    172 
    173     cout << "****************vec_data.push_back(data2)" << endl;
    174     vec_data.push_back(data2);
    175     Sleep(2 * vec_data.size());
    176 
    177     cout << "****************vec_data.push_back(data3)" << endl;
    178     vec_data.push_back(data3);
    179     Sleep(2 * vec_data.size());
    180 
    181     cout << "****************vec_data.push_back(data4)" << endl;
    182     vec_data.push_back(data4);
    183     Sleep(2 * vec_data.size());
    184 
    185     cout << "****************vec_data.push_back(data5)" << endl;
    186     vec_data.push_back(data5);
    187     Sleep(2 * vec_data.size());
    188 
    189     cout << "****************vec_data.push_back(data6)" << endl;
    190     vec_data.push_back(data6);
    191     Sleep(2 * vec_data.size());
    192 
    193     cout << "****************vec_data.push_back(data7)" << endl;
    194     vec_data.push_back(data7);
    195     Sleep(2 * vec_data.size());
    196 
    197     cout << "****************vec_data.push_back(data8)" << endl;
    198     vec_data.push_back(data8);
    199     Sleep(2 * vec_data.size());
    200 
    201     cout << "****************vec_data.push_back(data9)" << endl;
    202     vec_data.push_back(data9);
    203     Sleep(2 * vec_data.size());
    204 
    205     cout << "****************vec_data.push_back(data10)" << endl;
    206     vec_data.push_back(data10);
    207     Sleep(2 * vec_data.size());
    208 
    209     cout << "===============show vector by iterator 2" << endl;
    210     for (vector<CData>::iterator itr = vec_data.begin(); itr != vec_data.end(); itr++)
    211     {
    212         cout << "address of itr is " << &(*itr) << "	value is " << itr->toString() << endl;
    213     }
    214 
    215     // 上面的日志信息显示。vector开始已经有了足够大的地址空间来保存这10个变量,所以,他就不会再频繁创建新的内存地址和创建新对象了。
    216     // 这样的方式,可以节省很多的系统开销。
    217 
    218     cout << "===============clear vector 2" << endl;
    219     // vector中的元素不是指针,此处的清理,会调用析构函数。
    220     vec_data.clear();
    221 
    222     cout << "======================end of process" << endl;
    223 
    224     return 0;
    225 }
    View Code

    程序的结果:
    process begin at 00D1173A
    CData(int i,string &s)  [sequence:1 | remark:baby_test] 00CAFAD0
    CData(int i,string &s)  [sequence:2 | remark:baby_test] 00CAFAA8
    CData(int i,string &s)  [sequence:3 | remark:baby_test] 00CAFA80
    CData(int i,string &s)  [sequence:4 | remark:baby_test] 00CAFA58
    CData(int i,string &s)  [sequence:5 | remark:baby_test] 00CAFA30
    CData(int i,string &s)  [sequence:6 | remark:baby_test] 00CAFA08
    CData(int i,string &s)  [sequence:7 | remark:baby_test] 00CAF9E0
    CData(int i,string &s)  [sequence:8 | remark:baby_test] 00CAF9B8
    CData(int i,string &s)  [sequence:9 | remark:baby_test] 00CAF990
    CData(int i,string &s)  [sequence:10 | remark:baby_test]        00CAF968
    push CData to vector
    max size of vector<CData> is 134217727
    size of vector<CData> is 0
    ****************vec_data.push_back(data1)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 010485A8
    ****************vec_data.push_back(data2)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 01046F60
    ~CData()        010485A8
    CData(const CData &data)        [sequence:2 | remark:baby_test] 01046F80
    ****************vec_data.push_back(data3)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 0104D230
    CData(const CData &data)        [sequence:2 | remark:baby_test] 0104D250
    ~CData()        01046F60
    ~CData()        01046F80
    CData(const CData &data)        [sequence:3 | remark:baby_test] 0104D270
    ****************vec_data.push_back(data4)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 0104D2C0
    CData(const CData &data)        [sequence:2 | remark:baby_test] 0104D2E0
    CData(const CData &data)        [sequence:3 | remark:baby_test] 0104D300
    ~CData()        0104D230
    ~CData()        0104D250
    ~CData()        0104D270
    CData(const CData &data)        [sequence:4 | remark:baby_test] 0104D320
    ****************vec_data.push_back(data5)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 0104E430
    CData(const CData &data)        [sequence:2 | remark:baby_test] 0104E450
    CData(const CData &data)        [sequence:3 | remark:baby_test] 0104E470
    CData(const CData &data)        [sequence:4 | remark:baby_test] 0104E490
    ~CData()        0104D2C0
    ~CData()        0104D2E0
    ~CData()        0104D300
    ~CData()        0104D320
    CData(const CData &data)        [sequence:5 | remark:baby_test] 0104E4B0
    ****************vec_data.push_back(data6)
    CData(const CData &data)        [sequence:6 | remark:baby_test] 0104E4D0
    ****************vec_data.push_back(data7)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 0104D230
    CData(const CData &data)        [sequence:2 | remark:baby_test] 0104D250
    CData(const CData &data)        [sequence:3 | remark:baby_test] 0104D270
    CData(const CData &data)        [sequence:4 | remark:baby_test] 0104D290
    CData(const CData &data)        [sequence:5 | remark:baby_test] 0104D2B0
    CData(const CData &data)        [sequence:6 | remark:baby_test] 0104D2D0
    ~CData()        0104E430
    ~CData()        0104E450
    ~CData()        0104E470
    ~CData()        0104E490
    ~CData()        0104E4B0
    ~CData()        0104E4D0
    CData(const CData &data)        [sequence:7 | remark:baby_test] 0104D2F0
    ****************vec_data.push_back(data8)
    CData(const CData &data)        [sequence:8 | remark:baby_test] 0104D310
    ****************vec_data.push_back(data9)
    CData(const CData &data)        [sequence:9 | remark:baby_test] 0104D330
    ****************vec_data.push_back(data10)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 0104ED28
    CData(const CData &data)        [sequence:2 | remark:baby_test] 0104ED48
    CData(const CData &data)        [sequence:3 | remark:baby_test] 0104ED68
    CData(const CData &data)        [sequence:4 | remark:baby_test] 0104ED88
    CData(const CData &data)        [sequence:5 | remark:baby_test] 0104EDA8
    CData(const CData &data)        [sequence:6 | remark:baby_test] 0104EDC8
    CData(const CData &data)        [sequence:7 | remark:baby_test] 0104EDE8
    CData(const CData &data)        [sequence:8 | remark:baby_test] 0104EE08
    CData(const CData &data)        [sequence:9 | remark:baby_test] 0104EE28
    ~CData()        0104D230
    ~CData()        0104D250
    ~CData()        0104D270
    ~CData()        0104D290
    ~CData()        0104D2B0
    ~CData()        0104D2D0
    ~CData()        0104D2F0
    ~CData()        0104D310
    ~CData()        0104D330
    CData(const CData &data)        [sequence:10 | remark:baby_test]        0104EE48
    ===============show vector by iterator
    address of itr is 0104ED28      value is [sequence:1 | remark:baby_test]
    address of itr is 0104ED48      value is [sequence:2 | remark:baby_test]
    address of itr is 0104ED68      value is [sequence:3 | remark:baby_test]
    address of itr is 0104ED88      value is [sequence:4 | remark:baby_test]
    address of itr is 0104EDA8      value is [sequence:5 | remark:baby_test]
    address of itr is 0104EDC8      value is [sequence:6 | remark:baby_test]
    address of itr is 0104EDE8      value is [sequence:7 | remark:baby_test]
    address of itr is 0104EE08      value is [sequence:8 | remark:baby_test]
    address of itr is 0104EE28      value is [sequence:9 | remark:baby_test]
    address of itr is 0104EE48      value is [sequence:10 | remark:baby_test]
    ===============clear vector 1
    ~CData()        0104ED28
    ~CData()        0104ED48
    ~CData()        0104ED68
    ~CData()        0104ED88
    ~CData()        0104EDA8
    ~CData()        0104EDC8
    ~CData()        0104EDE8
    ~CData()        0104EE08
    ~CData()        0104EE28
    ~CData()        0104EE48
    size of vector<CData> is 0
    capacity of vector<CData> is 20
    ****************vec_data.push_back(data1)
    CData(const CData &data)        [sequence:1 | remark:baby_test] 0104EEF8
    ****************vec_data.push_back(data2)
    CData(const CData &data)        [sequence:2 | remark:baby_test] 0104EF18
    ****************vec_data.push_back(data3)
    CData(const CData &data)        [sequence:3 | remark:baby_test] 0104EF38
    ****************vec_data.push_back(data4)
    CData(const CData &data)        [sequence:4 | remark:baby_test] 0104EF58
    ****************vec_data.push_back(data5)
    CData(const CData &data)        [sequence:5 | remark:baby_test] 0104EF78
    ****************vec_data.push_back(data6)
    CData(const CData &data)        [sequence:6 | remark:baby_test] 0104EF98
    ****************vec_data.push_back(data7)
    CData(const CData &data)        [sequence:7 | remark:baby_test] 0104EFB8
    ****************vec_data.push_back(data8)
    CData(const CData &data)        [sequence:8 | remark:baby_test] 0104EFD8
    ****************vec_data.push_back(data9)
    CData(const CData &data)        [sequence:9 | remark:baby_test] 0104EFF8
    ****************vec_data.push_back(data10)
    CData(const CData &data)        [sequence:10 | remark:baby_test]        0104F018
    ===============show vector by iterator 2
    address of itr is 0104EEF8      value is [sequence:1 | remark:baby_test]
    address of itr is 0104EF18      value is [sequence:2 | remark:baby_test]
    address of itr is 0104EF38      value is [sequence:3 | remark:baby_test]
    address of itr is 0104EF58      value is [sequence:4 | remark:baby_test]
    address of itr is 0104EF78      value is [sequence:5 | remark:baby_test]
    address of itr is 0104EF98      value is [sequence:6 | remark:baby_test]
    address of itr is 0104EFB8      value is [sequence:7 | remark:baby_test]
    address of itr is 0104EFD8      value is [sequence:8 | remark:baby_test]
    address of itr is 0104EFF8      value is [sequence:9 | remark:baby_test]
    address of itr is 0104F018      value is [sequence:10 | remark:baby_test]
    ===============clear vector 2
    ~CData()        0104EEF8
    ~CData()        0104EF18
    ~CData()        0104EF38
    ~CData()        0104EF58
    ~CData()        0104EF78
    ~CData()        0104EF98
    ~CData()        0104EFB8
    ~CData()        0104EFD8
    ~CData()        0104EFF8
    ~CData()        0104F018
    ======================end of process
    ~CData()        00CAF968
    ~CData()        00CAF990
    ~CData()        00CAF9B8
    ~CData()        00CAF9E0
    ~CData()        00CAFA08
    ~CData()        00CAFA30
    ~CData()        00CAFA58
    ~CData()        00CAFA80
    ~CData()        00CAFAA8
    ~CData()        00CAFAD0

  • 相关阅读:
    微服务简介
    Apache httpd.conf
    搭建PHP开发环境
    搭建Apache开发环境
    Swift 项目编译优化(一)
    用Flutter 写一个简单页面
    Sign In With Apple(一)(转)
    Xcode DeviceSupport
    MQTT初始篇笔记整理
    UITableView使用过程中可能遇到的问题
  • 原文地址:https://www.cnblogs.com/babyha/p/6443781.html
Copyright © 2020-2023  润新知