这不是关于该主题的其他问题的完全相同的副本。我偶然发现了一些非常奇怪的事情并且无法理解这种情况。
struct Edge{
int vertex_a{ 0 };
int vertex_b{ 0 };
};
typedef std::vector<Edge> EdgeList;
struct Vertex{
std::vector<int> edge_indices;
};
typedef std::vector<Vertex> VertexList;
void ContractEdge(int edge_index){
static int iter = 0;
++iter;
auto& edge = edge_list[edge_index];
auto& vertex_a = vertex_list[edge.vertex_a - 1];
auto& vertex_b = vertex_list[edge.vertex_b - 1];
auto dead_vertex_index = edge.vertex_b;
std::vector<int> self_edge_array;
auto& indices = vertex_b.edge_indices;
for (auto it = indices.begin(); it != indices.end();++it){
auto current_index = *it;
auto& edge_of_b = edge_list[current_index];
if (edge_of_b.vertex_a == dead_vertex_index){
edge_of_b.vertex_a = edge.vertex_a;
}
if (edge_of_b.vertex_b == dead_vertex_index){
edge_of_b.vertex_b = edge.vertex_a;
}
if (edge_of_b.vertex_a == edge_of_b.vertex_b){
self_edge_array.push_back(current_index);
}
else{
//this is the line where reallocation happens
vertex_a.edge_indices.push_back(current_index);
}
}
RemoveVertexFromGraph(dead_vertex_index);
int d = 0;
for (auto& x : edge_list){
if ((x.vertex_a > vertex_list.size()) || (x.vertex_b > vertex_list.size()))
++d;
}
if (d)
++d;
std::sort(self_edge_array.rbegin(), self_edge_array.rend());
for (auto self_edge : self_edge_array){
RemoveEdgeFromGraph(self_edge);
}
}
在这个函数的中间,我迭代一个顶点的索引向量,偶尔将一些值推回到其他顶点的索引向量。
在运行此代码时,我开始收到错误消息&#34; Vector iterator not icrementable&#34;。
我决定进一步调试,发现当我在push_back
处执行一定数量的vertex_a.edge_indices.push_back(current_index)
时,向量的大小和容量都是19,向量实现调用{{ 1}}方法,它调用一些reallocate方法。
之后,索引向量会自动重新分配,其中的所有指针都指向另一个内存块。这就是为什么auto it iterator不能也不能比较而不是递增的原因,因为它指向一个错误的地方变得无效。
答案 0 :(得分:2)
感谢您的评论。事实证明,在问题发生的那一刻,我实际上正在反击我正在迭代的相同向量。 当然,这会使迭代器失效。 因此,问题出现在糟糕的数据组织和糟糕的编码风格中。 我现在正在看你的评论,我现在明白我的代码非常糟糕。谢谢你的指示。 我也没有把整个代码放在一边审查,因为我认为这样就足够了但我确定至少可以证明它是一个类,并且它有一些成员。 并揭示更多的结构。再次抱歉。 我想我可能需要提出一些其他数据结构,可能不会进行任何动态重新分配,直到内部算法完成。我知道,0和1索引也是蹩脚的。我只是在做一个课程任务,任务是在txt文件中,并且有一个基于1的索引。
是的,d和iter是断点