该程序初步演示了我对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的内存分配机制分析的更多相关文章

  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. 寻找最大(小)的K个数

    <<编程之美>>一书中提到了寻找最大的K个数的问题,问题可以简单描述为:在长度为N的数组中,寻找第K(K<N)个最大的数.问题的解法涉及到了很多排序算法,对我们理解和运用 ...

  2. HackerRank - fibonacci-modified 【大数】

    思路 用PYTHON 或 JAVA 干掉 AC代码 a, b, n = map(int, input().split()) for i in range (2, n, 1) : temp = b b ...

  3. Linux Shell基础 位置参数变量、预定义变量

    位置参数变量 在 Linux 的命令行中,当一条命令或脚本执行时,后面可以跟多个参数,我们使用位置参数变量来表示这些参数.其中,$0 代表命令行本身,$1 代表第 1 个参数,$2 代表第 2 个参数 ...

  4. 【leetcode刷题笔记】Median of Two Sorted Arrays

    There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted ...

  5. JVM内存的堆、栈和方法区

    JVM的内存分为堆.栈.方法区和程序计数器4个区域 存储内容:基本类型,对象引用,对象本身,class,常量,static变量 堆: 拥有者:所有线程 内容:对象本身,不存放基本类型和对象引用 垃圾回 ...

  6. win7 与 Ubuntu 16.04 文件传送

    win7 与 Ubuntu 16.04 文件传送 环境:主机系统为win7,虚拟机为vmware12, 虚拟系统为ubuntu 16.04 方案一: 通过虚拟机vmware的共享文件夹实现. 方案二: ...

  7. nginx location proxy pass

    nginx: 192.168.1.23作为nginx反向代理机器 目标机器192.168.1.5上部署一个8090端口的nginx [root@localhost conf.d]# cat test. ...

  8. java基础(2)-面向对象(1)

    面向对象 面向对象思想 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程:强调的是功能行为 面向对象:将功能封装进对象,强调具备了功能的对象 面向对象是基于面向过程的 面向对象举例 ...

  9. 字符在内存中最终的表示形式是什么?是某种字符编码还是码位(Code Point)?

    字符在内存中最终的表示形式是什么?是某种字符编码还是码位(Code Point)? 根据我的了解,编码中有三个核心概念:1. 字符集(Character Set),可以说是一个抽象概念,字符的合集2. ...

  10. php+JS进度条

    <?phpini_set('max_execution_time','0');//设置本页面加载时间无限制 echo "<div style='border: 1px solid ...