vector为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。
当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间,这样性能难以接受。因此STL实现者在对vector进行内存分配时,其实际分配的容量要比当前所需的空间多一些。就是说,vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。
通过下面代码可以更清楚的看到vector在push_back、insert、reserve、resize时占用内存的变化。
#include
#include
#include
#include
using
namespace std;
//打印vector元素
#define Display(v) copy(v.begin(),
v.end(), ostream_iterator(cout, " ")); cout<
/*
*
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 v0, v1, v2;
//空的vector
vector vi(data_int, data_int+5);
vector vd(data_double,
data_double+5);
cout<
//输出:1073741823
//说明vector可分配的内存大小为
1073741823*4B 即为 4GB
//max_size()源码为:size_type max_size() const { return
static_cast(-1) / sizeof(value_type); }
vector::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::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
// www.yzyedu.com
// size:0 capacity:8
//说明clear函数不能回收vector占用的内存空间
return
0;
}
另外,resize的时候内存分配机制还有些疑问!