该程序初步演示了我对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. jmeter 监控插件JMeterPlugins&PerfMon安装

    下载地址:http://jmeter-plugins.org/downloads/all/ PerfMon: 用来监控Server的CPU.I/O.Memory等情况 ServerAgent-2.2. ...

  2. 解决eclipse不识别Android手机的问题

    from:http://www.apkbus.com/blog-3-39569.html 搭好Android开发环境之后,用模拟器运行Android程序没有问题,但是将手机用USB连接电脑后,电脑不识 ...

  3. 解决PowerDesigner 反向工程没有注释(备注)

    1. 列注释 原来代码: {OWNER, TABLE, S, COLUMN, DTTPCODE, LENGTH, SIZE, PREC, COMPUTE, NOTNULL, IDENTITY, DOM ...

  4. iOS self 和 super 学习

    有人问我 这个问题 回答错了,题干大概是说 [self class] 和 [super class]打印结果 是不是一样的. 我睁着眼睛说是不一样的 .因为我明明记得 几天前 做 DFS 获取反射基类 ...

  5. octotree神器 For Github and GitLab 火狐插件

    Code tree for GitHub and GitLabExtension to show code tree for GitHub and GitLab. Useful for develop ...

  6. github使用——如何恢复被删去文件。

    首先git删除文件包括以下几种情况 删除本地文件,但是未添加到暂存区: 删除本地文件,并且把删除操作添加到了暂存区: 把暂存区的操作提交到了本地git库: 把本地git库的删除记录推送到了远程服务器g ...

  7. R中的参数传递函数:commandArgs(),getopt().

    1.commandArgs(),是R自带的参数传递函数,属于位置参数. ##test.R args=commandArgs(T) print (args[1])##第一个外部参数 print (arg ...

  8. R中的运算符,条件语句,控制语句

    1.运算符 算术运算符:+,-,*,/ 关系运算符:==,!=,>,>=,<,<= 逻辑运算符:&,|,&&,||,! &和|称为短逻辑符,&a ...

  9. 手把手教你使用eclipse+qemu+gdb来单步调试ARM内核【学习笔记】

    平台信息:linux4.0 平台:qemu 作者:庄泽彬 说明:笨叔叔的Linux视频的笔记 一.编译linux源码 export CROSS_COMPILE=arm-linux-gnueabi- e ...

  10. Go 文件操作

    一.读取文件 普通版 ioutil版 bufio版 二.文件写入 普通版 ioutil版 bufio版 三.文件复制 ioCopy 1.普通版读取文件 package main import ( &q ...