向量中的指针问题

时间:2015-05-12 04:43:03

标签: c++

我试图刷新我的C ++,因为我使用它已经有一段时间了,我遇到了存储指针的问题。在下面的方法结束时,向量“graph”包含我插入的所有顶点,但是应该添加的边缘已损坏(我可以看到调试器中的边缘,但它们的数据是垃圾)。我想知道是否有人可以帮忙指导?

谢谢!

作为参考,add_edge函数声明如下:

std::vector<vertice*> m_edges;
    ...
    ...
void add_edge(vertice* n);
{
    m_edges.push_back(n);
}

主要问题:

std::vector<vertice> graph;
std::string line;

//Iterate over line
int lineCount = 0;
while(getline(file, line))
{
    auto vertices = parse_line(line);
    for(size_t i = 0; i < vertices.size(); ++i)
    {
        auto result = std::find_if(
            graph.begin(),
            graph.end(),
            [&] (vertice cVert) { return cVert.getName() == vertices.at(i); });

        std::vector<vertice>::size_type currPos = 
            std::distance(graph.begin(), result);

        if(result == graph.end())
        {
            graph.emplace_back(vertice{vertices.at(i)});
        }

        if(i == 0) { continue; }
        graph.at(lineCount).add_edge(currPos == graph.size() ? 
            &graph.back() : &graph.at(currPos));
    }

    ++lineCount;
}

//The vector graph has corrupt nodes here

2 个答案:

答案 0 :(得分:2)

插入新元素时,指向std::vector内容的指针可能会失效,例如在std::vector::emplace_back中:

  

如果new size()大于capacity(),则所有迭代器和引用(包括last-the-end迭代器)都将失效。否则只有过去的迭代器无效。

考虑std::vector::reserve在需要重新分配元素或使用不同的容器之前保留容量,容器不会使插入上的引用无效,可能是std::list

答案 1 :(得分:1)

问题在于:

auto v = currPos == graph.size() ? &graph.back() : &graph.at(currPos);

您正在获取graph元素的地址,但是如果graph向量在emplace_back期间调整大小,则最终会出现悬空指针。解决方案是修复向量的大小而不是push_back / emplace_back,以直接使用std::vector::operator[],或通过std::vector::reserve保留足够的内存。

可能不相关:

graph.emplace_back(vertice{vertices.at(i)});

应该只是

graph.emplace_back(vertices.at(i));

否则您正在调用复制构造函数see the definition of std::vector::emplace_back