移动向量的结构

时间:2014-10-10 01:20:39

标签: c++

我现在花了太多时间试图让以下代码段不是段错误。有人可以解释我为什么会这样做吗?

我知道问题出在某个未初始化的内存中。

#include <iostream>
#include <vector>

using namespace std;

struct node {
    vector<int> parents;
};

int main() {
    vector<node> nodedb;
    {
        node df;

        nodedb.push_back(move(df));
    }

    {
        node &existing_node = nodedb[0];

        for (int i = 0; i < 100; ++i) {
            node df;
            nodedb.push_back(move(df));

            existing_node.parents.push_back(0);
        }
    }

    return 0;
}

1 个答案:

答案 0 :(得分:5)

当你在循环中调用nodedb.push_back时,这可能会使向量元素的现有指针/迭代器无效。如果向量需要增长超出其当前内存分配,则会发生这种情况 - 分配了一大块内存,复制了向量内容,并释放了旧内存。

这意味着在某些时候existing_node变为无效,在此之后,取消引用它(通过existing_node.parents.push_back)会导致崩溃。

有几种方法可以解决这个问题:

  1. 修改向量时,不要对向量元素进行引用 - 直接通过索引引用元素(即nodedb[0].parents.push_back)。

  2. 正如@Neil Kirk上面所建议的那样,如果事先知道了向量的大小,那么在添加项目之前调用vector.reserve意味着向量不需要重新分配内存,因为它增长。除了解决当前问题,这也将改善您的表现。但是,在更改矢量时保持对矢量项的引用仍然不是很好的做法。

  3. 正如@Greg Hewgill所指出的,您可以更改为使用list而不是vector,因为列表具有以下属性:列表元素的现有迭代器/引用不会被无效更改列表(除非这些元素本身被删除)。