【发布时间】:2017-01-23 15:21:47
【问题描述】:
(这个问题可以扩展到其他容器)
我可以使用向量来存储大量数据,那么如果我没有很多内存,那么了解 c++ 如何管理对这个容器的分配非常重要。
a) 当对返回向量的函数进行分配时,该向量上的数据会在分配后立即清理,还是保留到最后一刻才能接收新数据?
b) 如果数据被立即销毁,函数过程中哪个状态向量来构建新数据?
b.1)如果数据保留了,这意味着我可以在内存中拥有两个巨大的向量(旧数据和新数据),直到分配(返回)?
c) 那么移动语义呢?它试图使用已经创建的空间? (如果数据没有像第一个问题那样立即销毁)
为了更好地演示,我写了一个小程序:
#include <vector>
#include <string>
using namespace std;
vector<string> func2() {
vector<string> f2(200000, string(20,'a'));
return f2;
}
vector<string> func4() {
vector<string> f4(400000, string(40,'b'));
//Now I have in memory 400000X40 + 200000X20?
return f4;
//after assignment I know I have just f4 content
}
vector<string> func1() {
vector<string> f1(100000, string(10,'c'));
return f10;
}
int main() {
vector<string> mVec;
mVec = func2(); //Create internally a vector with 20 units string with 20 'b' inside
mVec = func4(); //Create internally a vector with 40 units string with 40 'b' inside
mVec = func1(); //Create internally a vector with 10 units string with 10 'b' inside
return 0;
}
如果移动语义确实使用了现有空间,当 mVec 数据较少且需要分配更多(func2 到 func4)或反之(func4 到 func1)时,它是如何工作的。
【问题讨论】:
-
mVec = func2()使用移动赋值;函数内部f2分配的内部数据存储交给mVec。不执行进一步的分配或复制。与mVec = func4()相同——存储在函数内部分配,然后交给mVec;后者在接受新数据的所有权之前释放其先前的数据。与mVec = func1()相同。 -
一种更有效的方法可能是通过引用函数来传递向量。这可能会消除一些向量的复制(取决于优化设置和编译器)。
标签: c++ vector containers