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

  1. /*
  2. 功能说明:
  3. vector的内存分配机制分析。
  4. 代码说明:
  5. vector所管理的内存地址是连续的。程序在不断的push_back的过程中,如果当前所管理的内存不能装下新的元素的时候,程序会创建更大的地址连续的空间来保存更多的元素。
  6. 这种机制会引起大量的无用的复制和删除操作。如果vector的元素为类结构的时候,他就会有很多临时变量产生。通过复制构造函数和析构函数,可以看到这些操作。
  7. 实现方式:
  8.  
  9. 限制条件或者存在的问题:

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

程序的结果:
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

vector的内存分配机制分析的更多相关文章

  1. map的内存分配机制分析

    该程序演示了map在形成的时候对内存的操作和分配. 因为自己对平衡二叉树的创建细节理解不够,还不太明白程序所显示的日志.等我明白了,再来修改这个文档. /* 功能说明: map的内存分配机制分析. 代 ...

  2. list的内存分配机制分析

    该程序演示了list在内存分配时候的问题.里面的备注信息是我的想法. /* 功能说明: list的内存分配机制分析. 代码说明: list所管理的内存地址可以是不连续的.程序在不断的push_back ...

  3. memcached学习——memcached的内存分配机制Slab Allocation、内存使用机制LRU、常用监控记录(四)

    内存分配机制Slab Allocation 本文参考博客:https://my.oschina.net/bieber/blog/505458 Memcached的内存分配是以slabs为单位的,会根据 ...

  4. Keil C动态内存管理机制分析及改进(转)

    源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...

  5. 阿里面试官:小伙子,你给我说一下JVM对象创建与内存分配机制吧

    内存分配机制   逐步分析 类加载检查: 虚拟机遇到一条new指令(new关键字.对象的克隆.对象的序列化等)时,会先去检查这个指令的参数在常量池中定位到一个类的符号引用,并且这个符号引用代表的类是否 ...

  6. JVM的艺术-对象创建与内存分配机制深度剖析

    JVM的艺术-对象创建与内存分配机制深度剖析 引言 本章将介绍jvm的对象创建与内存分配.彻底带你了解jvm的创建过程以及内存分配的原理和区域,以及包含的内容. 对象的创建 类加载的过程 固定的类加载 ...

  7. Go语言内存分配机制

    前言: 本文是学习<<go语言程序设计>> -- 清华大学出版社(王鹏 编著) 的2014年1月第一版 做的一些笔记 , 如有侵权, 请告知笔者, 将在24小时内删除, 转载请 ...

  8. (转)C++ STL中的vector的内存分配与释放

    C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...

  9. Memcache简介 & 内存分配机制

            关于这个东西里面到底应该存放数据网上一直有很多种说法,有的说sql进行md5之后作为键值,结果作为内容存放,也有人说按照业务逻辑错放,反正是炒的不亦乐乎.        本人经过将近2 ...

随机推荐

  1. hadoop本地运行与集群运行

    开发环境: windows10+伪分布式(虚拟机组成的集群)+IDEA(不需要装插件) 介绍: 本地开发,本地debug,不需要启动集群,不需要在集群启动hdfs yarn 需要准备什么: 1/配置w ...

  2. ThinkPHP框架基础知识一

    ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来 ...

  3. 17 南宁区域赛 F - The Chosen One 【规律】

    题目链接 https://nanti.jisuanke.com/t/19972 题意 给出一个n 然后将 n 个数 标号为 1 -> n 按顺序排列 每次抽掉 奇数位的数 然后求最后剩下那个数字 ...

  4. Oracle表约束

    约束的概述: 约束是在表中定义的用于维护数据库完整性的一些规则 (1).主键约束 不能为空也不能重复 在一个表中只能定义一个主键约束 Oracle会在主键上建立一个唯一索引,可以指定唯一索引的存储位置 ...

  5. 在安装mysqli的时候,出现error: ext/mysqlnd/mysql_float_to_double.h: No such file or directory

    /application/php5.:: warning: /ext/mysqli/mysqli_api.c::: error: ext/mysqlnd/mysql_float_to_double.h ...

  6. CSS3手风琴下拉菜单

    在线演示 本地下载

  7. 类锁、对象锁、互斥锁与synchronized

    本文总结自: https://blog.csdn.net/luckey_zh/article/details/53815694 互斥锁: 若对象有互斥锁,则在任一时刻,只能有一个线程访问对象.类锁.对 ...

  8. cocos2dx打飞机项目笔记四:Enemy类和EnemyLayer类

    Enemy类没什么内容,就create和init方法,根据参数来创建不同的敌机,头文件代码如下: //飞机的类型 enum planeType {smallPlane, midPlane, bigPl ...

  9. WINDOWS下好用的MongoDB 3.0以上客户端工具: NoSql Manager

      WINDOWS下好用的MongoDB 3.0以上客户端工具: NoSql Manager https://www.mongodbmanager.com/download  

  10. springmvc请求参数的绑定和获取

    请求参数的绑定和获取: 获取页面请求的参数,是javaweb必不可少的一个环节,在struts中,是通过再Action中定义属性,或者Model的方式进行数据绑定和获取.需要提供setter或gett ...