vector的内存分配机制分析
该程序初步演示了我对vector在分配内存的时候的理解。可能有误差,随着理解的改变,改代码可以被修改。
- /*
- 功能说明:
- vector的内存分配机制分析。
- 代码说明:
- vector所管理的内存地址是连续的。程序在不断的push_back的过程中,如果当前所管理的内存不能装下新的元素的时候,程序会创建更大的地址连续的空间来保存更多的元素。
- 这种机制会引起大量的无用的复制和删除操作。如果vector的元素为类结构的时候,他就会有很多临时变量产生。通过复制构造函数和析构函数,可以看到这些操作。
- 实现方式:
- 限制条件或者存在的问题:
- 无
- */
- #include <iostream>
- #include <string>
- #include <vector>
- #include <windows.h>
- using namespace std;
- class CData
- {
- public:
- CData()
- {
- sequence = ;
- this->remark = "default string";
- cout << "CData()\t" << toString() <<"\t"<< this << endl;
- }
- CData(int i,string &s)
- {
- this->sequence = i;
- this->remark = s;
- cout << "CData(int i,string &s)\t" << toString() << "\t" << this << endl;
- }
- CData(const CData &data)
- {
- this->sequence = data.sequence;
- this->remark = data.remark;
- cout << "CData(const CData &data)\t" << toString() << "\t" << this << endl;
- }
- CData operator = (const CData &data)
- {
- this->sequence = data.sequence;
- this->remark = data.remark;
- cout << "CData operator = (const CData &data)\t" << toString() << "\t" << this << endl;
- return *this;
- }
- void setSequence(const int i)
- {
- this->sequence = i;
- }
- void setRemark(const string &s)
- {
- this->remark = s;
- }
- string toString() const
- {
- char tmp[] = { };
- sprintf(tmp, "[sequence:%d | remark:%s]", this->sequence, this->remark.c_str());
- //此处应该有内存复制操作,所以不用担心返回后tmp数组所指向的内存被修改或者不存在的情况。
- return tmp;
- }
- ~CData()
- {
- cout << "~CData()\t" << this << endl;
- }
- protected:
- private:
- int sequence;
- string remark;
- };
- int main(int argc, char **argv)
- {
- cout << "process begin at " << (void*)&main << endl;
- string str = "baby_test";
- CData data1(, str);
- CData data2(, str);
- CData data3(, str);
- CData data4(, str);
- CData data5(, str);
- CData data6(, str);
- CData data7(, str);
- CData data8(, str);
- CData data9(, str);
- CData data10(, str);
- cout << "push CData to vector" << endl;
- vector<CData> vec_data;
- cout << "max size of vector<CData> is " << vec_data.max_size() << endl;
- cout << "size of vector<CData> is " << vec_data.size() << endl;
- cout << "****************vec_data.push_back(data1)" << endl;
- vec_data.push_back(data1);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data2)" << endl;
- vec_data.push_back(data2);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data3)" << endl;
- vec_data.push_back(data3);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data4)" << endl;
- vec_data.push_back(data4);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data5)" << endl;
- vec_data.push_back(data5);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data6)" << endl;
- vec_data.push_back(data6);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data7)" << endl;
- vec_data.push_back(data7);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data8)" << endl;
- vec_data.push_back(data8);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data9)" << endl;
- vec_data.push_back(data9);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data10)" << endl;
- vec_data.push_back(data10);
- Sleep( * vec_data.size());
- // 程序到此为止,日志显示的比较怪异。
- // 具体来说,就是,将CData对象push到向量中的时候,程序会通过复制构造函数,创建一些临时变量。
- // 创建临时变量的原因分析:这可能与vector的内存分配方式有关。vector所创建的对象的内存的地址是连续的。
- // 当当前的vector所拥有内存不能装入新的元素的时候,程序会创建开辟新的地址连续的空间,并将原来地址中的元素全部复制一份,保存到新的地址中。然后在删除原来的地址中的对象。
- cout << "===============show vector by iterator" << endl;
- for (vector<CData>::iterator itr = vec_data.begin(); itr != vec_data.end(); itr++)
- {
- // 显示的地址信息,是最后一次push的时候所复制的对象的地址。
- cout << "address of itr is " << &(*itr) << "\tvalue is " << itr->toString() << endl;
- }
- cout << "===============clear vector 1" << endl;
- // vector中的元素不是指针,此处的清理,会调用析构函数。
- vec_data.clear();
- // 根据上面的分析,再次测试。
- // 本次测试是在将元素push到vector中之前,先为vector申请“足够大”的内存。
- vec_data.reserve();
- cout << "size of vector<CData> is " << vec_data.size() << endl;
- cout << "capacity of vector<CData> is " << vec_data.capacity() << endl;
- cout << "****************vec_data.push_back(data1)" << endl;
- vec_data.push_back(data1);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data2)" << endl;
- vec_data.push_back(data2);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data3)" << endl;
- vec_data.push_back(data3);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data4)" << endl;
- vec_data.push_back(data4);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data5)" << endl;
- vec_data.push_back(data5);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data6)" << endl;
- vec_data.push_back(data6);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data7)" << endl;
- vec_data.push_back(data7);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data8)" << endl;
- vec_data.push_back(data8);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data9)" << endl;
- vec_data.push_back(data9);
- Sleep( * vec_data.size());
- cout << "****************vec_data.push_back(data10)" << endl;
- vec_data.push_back(data10);
- Sleep( * vec_data.size());
- cout << "===============show vector by iterator 2" << endl;
- for (vector<CData>::iterator itr = vec_data.begin(); itr != vec_data.end(); itr++)
- {
- cout << "address of itr is " << &(*itr) << "\tvalue is " << itr->toString() << endl;
- }
- // 上面的日志信息显示。vector开始已经有了足够大的地址空间来保存这10个变量,所以,他就不会再频繁创建新的内存地址和创建新对象了。
- // 这样的方式,可以节省很多的系统开销。
- cout << "===============clear vector 2" << endl;
- // vector中的元素不是指针,此处的清理,会调用析构函数。
- vec_data.clear();
- cout << "======================end of process" << endl;
- return ;
- }
程序的结果:
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的内存分配机制分析的更多相关文章
- map的内存分配机制分析
该程序演示了map在形成的时候对内存的操作和分配. 因为自己对平衡二叉树的创建细节理解不够,还不太明白程序所显示的日志.等我明白了,再来修改这个文档. /* 功能说明: map的内存分配机制分析. 代 ...
- list的内存分配机制分析
该程序演示了list在内存分配时候的问题.里面的备注信息是我的想法. /* 功能说明: list的内存分配机制分析. 代码说明: list所管理的内存地址可以是不连续的.程序在不断的push_back ...
- memcached学习——memcached的内存分配机制Slab Allocation、内存使用机制LRU、常用监控记录(四)
内存分配机制Slab Allocation 本文参考博客:https://my.oschina.net/bieber/blog/505458 Memcached的内存分配是以slabs为单位的,会根据 ...
- Keil C动态内存管理机制分析及改进(转)
源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...
- 阿里面试官:小伙子,你给我说一下JVM对象创建与内存分配机制吧
内存分配机制 逐步分析 类加载检查: 虚拟机遇到一条new指令(new关键字.对象的克隆.对象的序列化等)时,会先去检查这个指令的参数在常量池中定位到一个类的符号引用,并且这个符号引用代表的类是否 ...
- JVM的艺术-对象创建与内存分配机制深度剖析
JVM的艺术-对象创建与内存分配机制深度剖析 引言 本章将介绍jvm的对象创建与内存分配.彻底带你了解jvm的创建过程以及内存分配的原理和区域,以及包含的内容. 对象的创建 类加载的过程 固定的类加载 ...
- Go语言内存分配机制
前言: 本文是学习<<go语言程序设计>> -- 清华大学出版社(王鹏 编著) 的2014年1月第一版 做的一些笔记 , 如有侵权, 请告知笔者, 将在24小时内删除, 转载请 ...
- (转)C++ STL中的vector的内存分配与释放
C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...
- Memcache简介 & 内存分配机制
关于这个东西里面到底应该存放数据网上一直有很多种说法,有的说sql进行md5之后作为键值,结果作为内容存放,也有人说按照业务逻辑错放,反正是炒的不亦乐乎. 本人经过将近2 ...
随机推荐
- hadoop本地运行与集群运行
开发环境: windows10+伪分布式(虚拟机组成的集群)+IDEA(不需要装插件) 介绍: 本地开发,本地debug,不需要启动集群,不需要在集群启动hdfs yarn 需要准备什么: 1/配置w ...
- ThinkPHP框架基础知识一
ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来 ...
- 17 南宁区域赛 F - The Chosen One 【规律】
题目链接 https://nanti.jisuanke.com/t/19972 题意 给出一个n 然后将 n 个数 标号为 1 -> n 按顺序排列 每次抽掉 奇数位的数 然后求最后剩下那个数字 ...
- Oracle表约束
约束的概述: 约束是在表中定义的用于维护数据库完整性的一些规则 (1).主键约束 不能为空也不能重复 在一个表中只能定义一个主键约束 Oracle会在主键上建立一个唯一索引,可以指定唯一索引的存储位置 ...
- 在安装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 ...
- CSS3手风琴下拉菜单
在线演示 本地下载
- 类锁、对象锁、互斥锁与synchronized
本文总结自: https://blog.csdn.net/luckey_zh/article/details/53815694 互斥锁: 若对象有互斥锁,则在任一时刻,只能有一个线程访问对象.类锁.对 ...
- cocos2dx打飞机项目笔记四:Enemy类和EnemyLayer类
Enemy类没什么内容,就create和init方法,根据参数来创建不同的敌机,头文件代码如下: //飞机的类型 enum planeType {smallPlane, midPlane, bigPl ...
- WINDOWS下好用的MongoDB 3.0以上客户端工具: NoSql Manager
WINDOWS下好用的MongoDB 3.0以上客户端工具: NoSql Manager https://www.mongodbmanager.com/download
- springmvc请求参数的绑定和获取
请求参数的绑定和获取: 获取页面请求的参数,是javaweb必不可少的一个环节,在struts中,是通过再Action中定义属性,或者Model的方式进行数据绑定和获取.需要提供setter或gett ...