【问题标题】:How do I push back to a vector<vector<Object>> in which I have only reserved memory?如何推回我只保留内存的 vector<vector<Object>> ?
【发布时间】:2021-05-18 05:21:07
【问题描述】:

所以我有一个成员vector&lt;vector&lt;Foo&gt;&gt; _meshMatrix 如果我这样做了

_meshMatrix.resize(_numRefElementsPerRow);
    for(unsigned int i = 0; i < _numRefElementsPerRow ; i++)
        _meshMatrix [i].resize(_numRefElementsPerColumn);

然后我有一个Foo 对象矩阵,我可以使用 [][] 访问它的元素

for(unsigned int row = 0; row < _numRefElementsPerRow; row++)
    for(unsigned int column = 0; column < _numRefElementsPerRow; column++)
        _meshMatrix [row][column] = someFooObject;

为了节省内存,因为某些矩阵位置不会被填满,我想使用reservepush_back,所以

_meshMatrix.reserve(_numRefElementsPerRow);
    for(unsigned int i = 0; i < _numRefElementsPerRow ; i++)
        _meshMatrix [i].reserve(_numRefElementsPerColumn);

但我不知道如何两次 push_back 进入这个矩阵

for(unsigned int row = 0; row < _numRefElementsPerRow; row++)
    for(unsigned int column = 0; column < _numRefElementsPerRow; column++)
        //_meshMatrix.??? = someFooObject; // how dO I use push_back here?

有什么想法吗?

【问题讨论】:

  • _meshMatrix 的大小为 时,您要保留的循环使用_meshMatrix [i]。调整大小和保留向量之间的内存消耗没有区别。
  • “一些矩阵位置不会被填满”——是否意味着矩阵是稀疏的?那些“零”只是在行的末尾,还是在中间?稀疏矩阵有一些特殊的格式,它们可能比一个向量更好。
  • @DanielLangr 这就像用小多边形填充在矩形内绘制的大多边形
  • @DanielLangr 这些格式是什么?
  • 对了,第一个resize调用和循环真的和单语句_meshMatrix = std::vector&lt;std::vector&lt;Foo&gt;&gt;(_numRefElementsPerRow, std::vector&lt;Foo&gt;(_numRefElementsPerColumn));一样

标签: c++ oop stl


【解决方案1】:

_meshMatrix [row].push_back(value)

仅供参考,您正在使用_numRefElementsPerRow 遍历行和列并为列保留空间。除非它们的大小相同,否则这是一个错误。 我想你的意思是使用_numRefElementsPerColumn


编辑:似乎我对您的代码做出了不正确的假设。我会浏览你的代码。 EDIT2:我不应该在深夜这样做。打字保留 -> 调整大小。固定。

vector<vector<Foo>> _meshMatrix;
_meshMatrix.reserve(_numRefElementsPerRow);

调用 resize default 会初始化 vector&lt;Foo&gt;_numRefElementsPerRow 元素。内存被分配和构造。

这里调用reserve分配了足够的内存来保存vector&lt;Foo&gt;_numRefElementsPerRow元素。这并不意味着已经构建了任何元素;您只确保行向量中有足够的空间容纳那么多。请注意,我将其称为行向量,因为您通过 _numRefElementsPerRow

分配它来保存一行中的元素数
    for(unsigned int i = 0; i < _numRefElementsPerRow ; i++)
        _meshMatrix [i].reserve(_numRefElementsPerColumn);

接下来为每列保留足够的内存。 但是您错过了一步。这是未定义的行为。您正在对尚未构造的对象调用resize。如果您要调用_meshMatrix.size(),它将返回0。要创建对象,您必须构造它们,例如这是有效的:

    vector<vector<Foo>> _meshMatrix;
    _meshMatrix.reserve(_numRefElementsPerRow);
    for(unsigned int i = 0; i < _numRefElementsPerRow ; i++) {
        _meshMatrix.push_back(); // <<< construct a vector<Foo> at the end
        _meshMatrix[i].reserve(_numRefElementsPerColumn);

现在如果你想为每一列添加元素,你可以这样做:

for (unsigned j = 0; j < _numRefElementsPerColumn; j++) {
    _meshMatrix[j].push_back(value); // <<< some value
}

把它放在一起:

    // Create empty vector for rows
    vector<vector<Foo>> _meshMatrix;
    // Allocate memory ahead of time for the elements
    _meshMatrix.reserve(_numRefElementsPerRow);

    for(unsigned int i = 0; i < _numRefElementsPerRow ; i++) {
        // Create a vector for column values
        _meshMatrix.emplace_back(); // or _meshMatrix.push_back({});
        // Allocate memory ahead of time for the elements
        _meshMatrix[i].reserve(_numRefElementsPerColumn);
        for (unsigned j = 0; j < _numRefElementsPerColumn; j++) {
            // Add values
            _meshMatrix[j].push_back(value); // <<< some value
        }
    }

【讨论】:

  • _meshMatrix[row] 在循环中不存在。您应该提供有关您的解决方案的更多详细信息。
  • 我是什么?行索引(外部用于)或第一列(内部用于)。
  • 对不起,错字。我的意思是行
  • @J.C.VegaO 一个向量必须至少有i 元素才能在其i-1-th 位置放置一个。保留内存并不会改变它。
  • Push_back 添加到向量的后面。您将值存储为第一行,然后将内部向量存储为列值。表达式_meshMatrix[row] 返回对列向量的引用。通过推回列向量,您正在添加列值。
【解决方案2】:

你可以像这样 push_back

for(unsigned int row = 0; row < _numRefElementsPerRow; row++)
{
    vector<Foo> meshMatrixCols;
    for(unsigned int column = 0; column < _numRefElementsPerRow; column++)
         meshMatrixCols.push_back(someObject); // how dO I use push_back here?

     _meshMatrix.push_back(meshMatrixCols);
}

【讨论】:

  • 不,你不能,因为根据 OP 的代码,_meshMatrix[row] 不存在。
  • 我认为这里保留了行 _meshMatrix.reserve(_numRefElementsPerRow);
  • @Villance “保留元素可以通过索引访问。” — 不,他们不能。 “它的工作原理”——这是最糟糕的推理。你甚至不知道Foo 是什么。在所有情况下,您都在尝试使用尚未构造/初始化的对象。
  • @Villance“以某种方式起作用”,直到它不起作用。允许编译器优化假设不存在未定义的行为,因为程序员有责任不创建未定义的行为。这可能会导致可怕的错误。
  • @Villance 像“它是 UB,但它以某种方式工作”是一个非常糟糕的建议。这只会产生以后很难修复的那种错误。
猜你喜欢
  • 2018-10-23
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多