向量的向量占用的内存

Posted

技术标签:

【中文标题】向量的向量占用的内存【英文标题】:Memory taken by a vector of vectors 【发布时间】:2020-02-26 18:41:40 【问题描述】:

vvint1vvint2 在内存中的预期差异(如果有)是什么? 每次push_back 发生时是否将vitest1 复制到新的内存位置? 每次push_back 发生时是否将vitest2 复制到新的内存位置?

typedef vector<int> vint_t;
typedef vector<vint_t> vvint_t;
size_t nvec = 2;
size_t nvvec = 3;
vvint_t vvint1(nvvec), vvint2(nvvec);
vint_t vitest2(nvec, 1);
for ( j = 0; j < nvvec; j++ ) 
    vint_t vitest1(nvec, 2);
    vvint1.push_back(vitest1);
    vvint2.push_back(vitest2);

【问题讨论】:

我认为您可能需要修改您的问题,看起来可能是拼写错误;它目前要求区分“vvint1 和 vvint1”。这与香蕉和香蕉的区别是一样的。 vvint1vvint2 将是相同的。每次使用push_pack 时,两者都会复制向量。 FWIW,二维向量不是你想要的。与int** 一样,std::vector&lt;std::vector&lt;int&gt;&gt; 缺少行之间的数据局部性。缺乏连续性会影响性能。相反,您应该做的是使用类模拟 sd 结构,并使用数学将所有数据存储在 1d 向量中,以将 2d 索引转换为 1d 索引。 无关:迟早会有人混淆vint_tvvint_t,因为名字很相似,而且名字很相似,很难被发现。跨度> @Tommy - 已修复(尽管我的意思很明显)。谢谢。 vvint_t vvint1(nvvec), vvint2(nvvec); aaaaaaaahhhh 代码太难读了。 【参考方案1】:

vvint1vvint2 最初都是使用 nvvec = 3 默认构造的成员(即 int 的空向量)创建的。

push_back 总是复制或移动,但在这种情况下,您没有提供右值引用,因此您将获得副本。查看std::move 了解更多信息。

您将相同数量的东西推送到两个向量。因此,vvint1vvint2 最终将具有相同的大小。

【讨论】:

【参考方案2】:

vvint1vvint2 内存要求为:

    (在堆栈上,在示例中)sizeof(vector&lt;vector&lt;int&gt;&gt;) 用于对象本身,这是相同的(vector 通常是 2-3 个指针,无论内部类型如何); (在堆上)2 * nvvec * sizeof(vector&lt;int&gt;) 用于内容(nvvec 最初和nvvec push_back-ed 在循环中);同样,vvint1vvint2 也是如此; (在堆上)存储在这些向量中的每个向量的内容。由于向量不共享内存,并且您按值存储它们,nvec * nnvec * sizeof(int)。还是一样。

所以总体要求是一样的: sizeof(vector&lt;vector&lt;int&gt;&gt;) + nvvec * sizeof(vector&lt;int&gt;) + nvec * nnvec * sizeof(int)

普通的vector&lt;int&gt; 会占用更少的空间,因为第 2 项不适用。但更重要的是,在vvint_t 中,内部向量可能有不同的长度,调整任何内部向量的大小不会影响其他向量。但这增加了复杂性,所以除非你真的需要,否则使用平面向量和计算索引会更简单;影像库就是这样做的。

关于第二部分,vitests 在每个 push_back 上都被复制。但从 C++11 开始,您可以编写 vvint1.push_back(std::move(vitest1));(或 vvint1.emplace_back(std::move(vitest1));)来代替移动。对于向量,这意味着新构建的向量无需复制即可获得vitest1 内容的所有权(因此vitest1 变为空)。这不会改变内存需求,但会减少分配,因为vitest(在构造时)分配的空间将被重用而不是被释放(在销毁时,在每次迭代结束时)。

【讨论】:

也许是2 * nvvec * sizeof(vector&lt;int&gt;)? (假设它以nvvec 开头并且有push_backs)。 糟糕,错过了。谢谢。编辑了答案。

以上是关于向量的向量占用的内存的主要内容,如果未能解决你的问题,请参考以下文章

oj教程--向量容器

为啥这个函数会占用大量内存?

数组 vs. 向量 vs. Boost::arrays

将向量存储在内存映射文件中

删除向量的元素

数组向量的内存布局是啥?