vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。
当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间,这样性能难以接受。因此STL实现者在对vector进行内存分配时,其实际分配的容量要比当前所需的空间多一些。就是说,vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。
通过下面代码可以更清楚的看到vector在push_back、insert、reserve、resize时占用内存的变化。
#include<cstdio>
#include<iostream>
#include<vector>
#include<iterator>
using namespace std; //打印vector元素
#define Display(v) copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ")); cout<<endl;
/*
* size()返回当前vector所容纳元素的数目
* max_size()函数返回当前vector所能容纳元素数量的最大值(包括可重新分配内存)
* capacity()函数返回当前vector在重新进行内存分配以前所能容纳的元素数量
*/
#define PrintSC(v) printf("size:%d\tcapacity:%d\t\n", v.size(), v.capacity()); int main(){
int i; printf("%d\t%d\n", sizeof(int), sizeof(double)); //输出int和double的字节数
//输出:4 8 int data_int[5] = {1,2,3,4,5};
double data_double[5] = {1.0,2.0,3.0,4.0,5.0};
vector<int> v0, v1, v2; //空的vector
vector<int> vi(data_int, data_int+5);
vector<double> vd(data_double, data_double+5); cout<<v0.max_size()<<endl;
//输出:1073741823
//说明vector可分配的内存大小为 1073741823*4B 即为 4GB
//max_size()源码为:size_type max_size() const { return static_cast<size_type>(-1) / sizeof(value_type); } vector<int>::iterator it0;
for(i=0; i<5; i++){
v0.push_back(i);
PrintSC(v0);
for(it0=v0.begin(); it0!=v0.end(); it0++)
printf("%p ", it0);
printf("\n");
}
//输出: size:1 capacity:1
// 00A72F00
// size:2 capacity:2
// 00A72C38 00A72C3C
// size:3 capacity:4
// 00A72F00 00A72F04 00A72F08
// size:4 capacity:4
// 00A72F00 00A72F04 00A72F08 00A72F0C
// size:5 capacity:8
// 00A72C38 00A72C3C 00A72C40 00A72C44 00A72C48
//说明使用push_back时,当size>capacity时,vector分配空间是成倍增长的,
//而且为了保证能有连续的内存空间,重分配空间可能造成元素存储位置改变 vector<int>::iterator it1;
v1.reserve(3);
PrintSC(v1);
for(i=0; i<5; i++){
it1 = v1.begin(); //每次必须重新定位,因为有可能插入元素有可能造成重新分配内存空间,原指针作废
v1.insert(it1, 1, i);
PrintSC(v1);
for(it1=v1.begin(); it1!=v1.end(); it1++)
printf("%p ", it1);
printf("\n");
}
//输出: size:1 capacity:3
// 00482F00
// size:2 capacity:3
// 00482F00 00482F04
// size:3 capacity:3
// 00482F00 00482F04 00482F08
// size:4 capacity:6
// 00482C60 00482C64 00482C68 00482C6C
// size:5 capacity:6
// 00482C60 00482C64 00482C68 00482C6C 00482C70
//说明使用insert的时候与push_back分配内存类似,都是不足时以两倍原大小重分配,
//如果使用了reserve,则会预留指定大小连续空间 v1.resize(7, -1);
PrintSC(v1);
for(it1=v1.begin(); it1!=v1.end(); it1++)
printf("%p ", it1);
printf("\n");
v1.resize(3, -1);
PrintSC(v1);
for(it1=v1.begin(); it1!=v1.end(); it1++)
printf("%p ", it1);
printf("\n");
v1.resize(13, -1);
PrintSC(v1);
for(it1=v1.begin(); it1!=v1.end(); it1++)
printf("%p ", it1);
printf("\n");
v1.resize(3, -1);
PrintSC(v1);
for(it1=v1.begin(); it1!=v1.end(); it1++)
printf("%p ", it1);
printf("\n");
//输出: size:7 capacity:10
// 005A2C80 005A2C84 005A2C88 005A2C8C 005A2C90 005A2C94 005A2C98
// size:3 capacity:10
// 005A2C80 005A2C84 005A2C88
// size:13 capacity:13
// 005A2CB0 005A2CB4 005A2CB8 005A2CBC 005A2CC0 005A2CC4 005A2CC8 005A2CCC 005A2CD0 005A2CD4 005A2CD8 005A2CDC 005A2CE0
// size:3 capacity:13
// 005A2CB0 005A2CB4 005A2CB8
//说明使用resize的时候当new_size大于当前capacity的时候,会发生内存重分配。 Display(v0);
PrintSC(v0);
v0.clear(); //删除当前vector中的所有元素
Display(v0);
PrintSC(v0);
//输出: 0 1 2 3 4
// size:5 capacity:8
//
// size:0 capacity:8
//说明clear函数不能回收vector占用的内存空间 return 0;
}
另外,resize的时候内存分配机制还有些疑问,参加这个讨论 http://bbs.csdn.net/topics/390739204
C++ STL vector 内存分配的更多相关文章
-
vector内存分配简单介绍
众所周知,vector的size()其实并不代表它占用的空间,它实际占用空间可以用capacity()查看 众所周知,push_back()时,如果size==capacity则会使capacity从 ...
-
C++的STL中vector内存分配方法的简单探索
STL中vector什么时候会自动分配内存,又是怎么分配的呢? 环境:Linux CentOS 5.2 1.代码 #include <vector> #include <stdio ...
-
STL vector 内存释放
最近在论坛看到一个提问帖子,问题是vector中存储了对象的指针,调用clear后这些指针如何删除? class Test { public: Test() {} ~Test() { cout < ...
-
vector内存分配
vector,map 这些容器还是在堆上分配的内存,在析构时是释放空间 vector在提高性能可以先reserve在push_back() reserve:决定capacity,但没有真正的分配内存, ...
-
关于 stl的内存分配的深浅拷贝
http://blog.csdn.net/u012501459/article/details/44132147
-
STL六大组件之——分配器(内存分配,好深奥的东西)
SGI设计了双层级配置器,第一级配置器直接使用malloc()和free(),第二级配置器则视情况采用不同的策略:当配置区块超过128bytes时,视之为“足够大”,便调用第一级配置器:当配置区小于1 ...
-
vector的内存分配与释放
1. vector内存分配 <Effective STL>中"条款14":使用reserve来避免不必要的重新分配 关于STL容器,最神奇的事情之一是只要不超过它们的最 ...
-
STL容器的内存分配
这篇文章参考的是侯捷的<STL源码剖析>,所以主要介绍的是SGI STL实现版本,这个版本也是g++自带的版本,另外有J.Plauger实现版本对应的是cl自带的版本,他们都是基于HP实现 ...
-
(转)C++ STL中的vector的内存分配与释放
C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...
随机推荐
-
Javascript初学篇章_5(对象)
对象 Javascript是一种面向对象的语言,因此可以使用面向对象的思想来进行javascript程序设计对象就是由一些彼此相关的属性和方法集合在一起而构成的一个数据实体.举个例子,一只猫是个对象, ...
-
java 垃圾回收
转自:http://www.360doc.com/content/13/0305/10/15643_269388816.shtml
-
【POJ】【3308】Paratroopers
网络流/二分图最小点权覆盖 sigh……这题……TLE&RE了好几发 建一个二分图,左边的每个结点代表行,右边的代表列,如果在(i,j)这个位置有一个外星人,那么我们就连一条边 (左 i -& ...
-
[HDU 1520] Anniversary party
Anniversary party Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
-
Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法
Ubuntu下QT控制台程序无法运行的解决方案以及XTerm的配置方法 最近由于老师要求要在Ubuntu下QT上进程多线程服务器的开发,虽然只是单纯的调用qt的network模块,但是为了避免麻烦,我 ...
-
生成自己的Webapi帮助文档(二)
经过今天一上午的修改,已经有个基础的框架了,其它功能只能是在实际使用中发现一个修改一个了. 以下是生成的结果示例: 相比昨天,几个Model都有修改,这里就不一一贴代码了,放个代码包上来,有需要的自己 ...
-
ios用户体验
如果转载此文,请注明出处:http://blog.csdn.net/paulery2012/article/details/25157347,谢谢! 前言: 本文是在阅读<ios用户体验> ...
-
万能动态库调用工具IDMA(InvokeDllMethodsAdvance)
万能动态库调用工具IDMA 开发者:马兆瑞 QQ/微信:624762543 百度云下载链接:https://pan.baidu.com/s/1skW5W4H CSDN下载链接:http://d ...
-
2018—2019-- 2网络对抗技术20165239Exp信息搜集 漏洞扫描
一.实验内容 二.实验步骤 1.各种搜索技巧的应用 2.DNS IP注册信息的查询 3.基本的扫描技术 主机发现 端口扫描 OS及服务版本探测 具体服务的查点 4.漏洞扫描 三.实验中遇到的问题 四. ...
-
CMake--List用法
list(LENGTH <list><output variable>) list(GET <list> <elementindex> [<ele ...