我试图刷新我的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
答案 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
。