c加加的vector拷贝

push发生内存拷贝

vector会涉及到内存拷贝,在push_back操作的时候会发生,这个c++的初学者很容易忽略。

看下面这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Test {
public:
Test(){
cout << "construct!" << endl;
}
// 定义拷贝函数,const Test & 类型参数
Test(const Test &b){
cout << "copy construct" << endl;
}
~Test(){
cout << "destruct" << endl;
}
};
int main(){
Test t1;
Test t2;
vector< Test> v;
v.push_back(t1);
v.push_back(t2);
return 0;
}

输出为:

1
2
3
4
5
6
7
8
9
10
construct!
construct!
copy construct
copy construct
copy construct
destruct
destruct
destruct
destruct
destruct

为什么会存在三次copy construct呢?vector 的 push_back 在发现空间不足时自动将空间以 2 的指数增长:0 -> 1 -> 2 -> 4 -> 8 -> 16 -> 32 ...

所以第一个copy是存入第一个元素的时候,第二个copy是vector扩容,把原来的vector的一个元素拷贝放入,再拷贝t2放入。

最后析构就是释放五个元素。

怎么减少拷贝次数呢?可以预先为vector设置容量,vector.reserve(4)就是预先开辟长度为4的空间。

swap释放内存

http://blog.jobbole.com/37700/

从push操作可以看出vector是有陷阱的,看到网上说clear不会清理内存,clear 不影响 capacity。swap才可以清理内存影响capacity,那就试试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main ()
{
for(int i=0; i<1000000; i++)
v.push_back("abcdefghijklmn");
cin >> ch;
// 此时检查内存情况 占用54M
v.clear();
cin >> ch;
// 此时再次检查, 仍然占用54M
cout << "Vector 的 容量为" << v.capacity() << endl;
// 此时容量为 1048576
vector<string>(v).swap(v);
cout << "Vector 的 容量为" << v.capacity() << endl;
// 此时容量为0
cin >> ch;
// 检查内存,释放了 10M+ 即为数据内存
return 0;
}

clear操作会把vector中的每个元素析构。使用临时变量和vector进行swap会释放vector占用的内存,记住一定要是临时变量,语句一执行完毕就会清理内存。