为什么c++中的3D向量比1D向量占用的内存大?
Why are 3D vectors in C++ larger in RAM than a 1D vector
我偶然发现一个STL向量定义如下:
vector < float > test;
test.resize(10000 * 10000 * 5);
在RAM中使用的空间比以下定义少得多:
std::vector<std::vector<std::vector< float > > > test;
test.resize(10000);
for(int i = 0;i < 10000;i++)
{
test[i].resize(10000);
for(int j = 0;j < 10000;j++)
{
test[i][j].resize(5);
}
}
线性向量方法(顶部)使用手动计算的正确RAM数量(2Gb)。所以我的问题是,为什么3D矢量比线性矢量使用更多的RAM,我发现它在这个例子中明显更多(大约4Gb)。
在前一种情况下,您可以:
sizeof(vector<float>) // outermost vector
+ 10000 * 10000 * 5 * sizeof(float) // xyz space
在后者中,你有:
sizeof(vector<vector<vector<float>>>) // outermost vector
+ 10000 * sizeof(vector<vector<float>>) // x axis
+ 10000 * 10000 * sizeof(vector<float>) // xy plane
+ 10000 * 10000 * 5 * sizeof<float> // xyz space
对于任何T
, sizeof(vector<T>)
的典型值都是3 * sizeof(T*)
,我认为这也是标准容量允许的最小值,必须与大小不同,因为reserve()
必须改变capacity()
的值,而不改变size()
的值。
vector类占用内存来保存额外的指针。当您分配为1D向量时,您只有1指针和它指向的大块内存。在向量的向量的向量的情况下,你有10,000 * 10,000 * 5个向量,每个向量都有一个4字节的指针,占用20亿个额外的字节,只是为了保存位置信息。
编辑
正如Andrey在评论中指出的那样,您实际上并没有设置10,000 * 10,000 * 5个向量,而是:
1D -顶层向量为它下面的10,000个向量留出空间
2D -这10,000个向量中的每一个都建立了另外10,000个向量
3D -最终的水平只是实际的数据,所以…
你有10,000个初始向量,下面的10,000 * 10,000个向量总共有100,010,000个向量。另一位用户提到每个向量大约占用20字节的空间(对于内存指针以及类中的其他成员,如大小,容量等),所以最终大约有20亿字节。
vector类有一些额外的开销。至少有一个指针和一个字段表示大小。在MS visual studio中,sizeof(std::vector)是20或24(启用了迭代器调试)。实际大小将取决于实现。
每个vector对象都有一个开销——因为它们可以是可变长度的,所以需要有指向起始点、所用位大小和容量的指针。
如果你有一个固定大小的3d形状,其中高度,宽度和长度是已知的,你可以将其转换为1D数组。这将是最有效的。
要做到这一点,给定x, y, z,你发现索引为x +宽度* ((z *高度)+ y)将进行转换。
- 迭代时从向量和内存中删除对象
- 我在二维向量中是否正确分配了内存
- 字符串共享内存映射的向量
- 具有 STL 向量类型成员的类的复制内存
- 重新分配向量时,向量中的内存会发生什么情况
- 向量的内存位置不连续
- 自己的自定义向量类. 内存重新分配
- 分配具有 2D 向量大小的变量的内存
- 在统一内存 CUDA C/C++ 中分配 2D 向量
- 将 c++ 向量转换为字符 ** 而不会泄漏内存
- 大向量和内存守恒c++
- 如果不初始化结构中的向量,它会自动为空还是具有随机内存位置的值?
- 从函数内对象的向量中释放内存
- C++ 使用数组初始化时的 STL 向量内存管理
- 向量:内存处的范围错误
- 指向对象的指针向量 - 内存泄漏
- 向量内存问题
- c++向量内存不足
- 从复制构造函数外部修改对象成员时导致向量内存损坏,但从复制构造函数内部修改时不会
- 可以使用std::vector capacity/size/rereserve手动管理向量内存分配吗