STL中Vector的内存分配机制
来源:互联网 发布:j罗 皇马 数据 编辑:程序博客网 时间:2024/04/30 09:04
关于vector,简单地讲就是一个动态数组,里面有一个指针指向一片连续的内存空间,当空间不够装下数据时会自动申请另一片更大的空间,然后把原有数据拷贝过去,接着释放原来的那片空间;当释放或者说是删除里面的数据时,其存储空间并不会释放,仅仅只是清空了里面的数据。接下来,我会详细地说说这些。
备注:本文的相关程序都是在windows 7+VS2008环境下测试。
一、首先,看看vector的内存分配机制:capacity()返回的是当前vector对象缓冲区(后面的对vector维护的内存空间皆称为缓冲区)实际申请的空间大小,而size()返回的是当前对象缓冲区中存储数据的个数,capacity永远是大于等于size的,当size和capacity相等时继续添加数据时vector会扩容。再来看看1.txt中的数据:
capacity=1,size=1
capacity=2,size=2
capacity=3,size=3
capacity=4,size=4
capacity=6,size=5
capacity=6,size=6
capacity=9,size=7
capacity=9,size=8
capacity=9,size=9
capacity=13,size=10
capacity=13,size=11
capacity=13,size=12
capacity=13,size=13
capacity=19,size=14
capacity=19,size=15
capacity=19,size=16
capacity=19,size=17
capacity=19,size=18
capacity=19,size=19
capacity=28,size=20
capacity=28,size=21
capacity=28,size=22
capacity=28,size=23
capacity=28,size=24
capacity=28,size=25
capacity=28,size=26
capacity=28,size=27
capacity=28,size=28
capacity=42,size=29
capacity=42,size=30
capacity=42,size=31
capacity=42,size=32
capacity=42,size=33
capacity=42,size=34
capacity=42,size=35
capacity=42,size=36
capacity=42,size=37
capacity=42,size=38
capacity=42,size=39
capacity=42,size=40
capacity=42,size=41
capacity=42,size=42
capacity=63,size=43
capacity=63,size=44
capacity=63,size=45
capacity=63,size=46
capacity=63,size=47
capacity=63,size=48
capacity=63,size=49
capacity=63,size=50
capacity=63,size=51
capacity=63,size=52
capacity=63,size=53
capacity=63,size=54
capacity=63,size=55
capacity=63,size=56
capacity=63,size=57
capacity=63,size=58
capacity=63,size=59
capacity=63,size=60
capacity=63,size=61
capacity=63,size=62
capacity=63,size=63
capacity=94,size=64
capacity=94,size=65
capacity=94,size=66
capacity=94,size=67
capacity=94,size=68
capacity=94,size=69
capacity=94,size=70
capacity=94,size=71
capacity=94,size=72
capacity=94,size=73
capacity=94,size=74
capacity=94,size=75
capacity=94,size=76
capacity=94,size=77
capacity=94,size=78
capacity=94,size=79
capacity=94,size=80
capacity=94,size=81
capacity=94,size=82
capacity=94,size=83
capacity=94,size=84
capacity=94,size=85
capacity=94,size=86
capacity=94,size=87
capacity=94,size=88
capacity=94,size=89
capacity=94,size=90
capacity=94,size=91
capacity=94,size=92
capacity=94,size=93
capacity=94,size=94
capacity=141,size=95
capacity=141,size=96
capacity=141,size=97
capacity=141,size=98
capacity=141,size=99
capacity=141,size=100
数据有点多,提炼下就是这样的:
capacity=1
capacity=2
capacity=3
capacity=4
capacity=6
capacity=9
capacity=13
capacity=19
capacity=28
capacity=42
capacity=63
capacity=94
capacity=141
看出其中的规律没?对,就是每次扩容都是增加当前空间的50%(第一次除外);
9+9/2=13;13+13/2=19;19+19/2=28……
其实STL的源码我们都可以看到的,具体就在你说安装的编译器目录下,例如,我的VS2008是在:安装目录\VC\include下面。你也可以在VS中直接选中#include <vector>右键打开。当然了,windows上的STL源码都是P.J. Plauger写的(PS:很牛B的博士,百度你就知道),大家都说可读性极差,我也这么认为,我们这些菜鸟还是看GCC中的STL源码吧。
\VC\include\vector中是这样扩容的:
对的,就是每次扩容50%。至于删除容器中数据的时候,缓冲区大小并不会改变,仅仅只是清楚了其中的数据,只有在析构函数调用的时候vector才会自动释放缓冲区。看看它的析构代码:
那么,我们可以在需要的时候强制释放缓冲区不?二、如何强制释放vector的缓冲区:
答案是可以的,既然析构时会释放空间,那么我们就可以换个方式调用析构函数。
三、如何使用提高性能:为了比较,我们用了三种方式来把100个数据存入vector中,分别是:1、直接每次push_back();2、使用resize()提前分配100个空间,然后push_back;3、使用reserve提前分配100个存储空间。MSDN中,这两个个函数的说明分别是:
reserveReserves a minimum length of storage for a vector object, allocating space if necessary.
resizeSpecifies a new size for a vector.
在这里我们初始化的时候使用感觉好像是差不多。
结果却不尽相同
reserve只是保持一个最小的空间大小,而resize则是对缓冲区进行重新分配,里面涉及到的判断和内存处理比较多,当然了在这里由于最初都是空的所以差别不大。
两者的区别查看:vector::reserve和vector::resize的区别。
由此可见,对于数据数目可以确定的时候,先预设空间大小是很有必要的。直接push_back数据频繁移动很是耗时(当然了,数据小的可以忽略的)。
真个测试程序的完整代码如下
参考了一些前辈的文章,能力有限,欢迎指教,相互学习。
- STL中vector的内存分配机制
- STL中Vector的内存分配机制
- vector的内存分配机制
- STL中vector的内存分配与释放
- STL中vector的内存分配与正确释放
- STL中vector内存分配策略剖析
- STL---vector内存分配
- stl-vector内存分配
- STL----vector的内存分配与释放
- STL-Vector内存机制
- vector的内存分配机制分析
- C++ STL中的vector的内存分配与释放
- C++ STL中的vector的内存分配与释放
- C++ STL中的vector的内存分配与释放
- C++ STL中的vector的内存分配与释放
- C++ STL中的vector的内存分配与释放
- C++ STL中的vector的内存分配与释放
- C++ STL中的vector的内存分配与释放
- 安装NetWeaver Java 7.5(Windows 2012 R2上)
- HDU 1325 Is It A Tree? 并查集判断是否成树
- Random rand =new Random(47);
- Oracle expdp/impdp导出导入命令及数据库备份
- Bellman-Ford求最短路径
- STL中Vector的内存分配机制
- 安全加密算法与数据签名总结(1)
- Undefined function 'conv2' for input arguments of type 'double' and attributes 'full 3d real'.
- 升级Android Studio2.2遇坑经历记录
- 线程、多线程与线程池总结
- DFS和BFS
- rmmod: chdir(/lib/modules): No such file or directory 解决方法
- 8086的寻址方式
- Codeforces723 E. One-Way Reform (欧拉路径)