C++ 访问迭代器值会导致SEG11故障
我有一个循环,可以删除邻接列表中的图边。看起来是这样的:C++ 访问迭代器值会导致SEG11故障,c++,C++,我有一个循环,可以删除邻接列表中的图边。看起来是这样的: void Graph::removeEdge(int a, int b) { vector<int>::iterator it = adjList[a].begin(); while(*it != b) it++; adjList[a].erase(it); it = adjList[b].begin(); while(*it != a) it++; adjList[b].erase(it); }
void Graph::removeEdge(int a, int b)
{
vector<int>::iterator it = adjList[a].begin();
while(*it != b) it++;
adjList[a].erase(it);
it = adjList[b].begin();
while(*it != a) it++;
adjList[b].erase(it);
}
这里可能发生的事情有: 1.卡在无限循环中,并且(在您的情况下:segfault) 2.删除不存在的迭代器(segfault) 要更正这些问题,请执行以下操作: 而不是:
while(*it != b) it++;
adjList[a].erase(it);
做:
如果到达
end
时未找到元素b
,则循环将结束,if
子句将确保删除现有的迭代器。此处可能发生的情况如下:
1.卡在无限循环中,并且(在您的情况下:segfault)
2.删除不存在的迭代器(segfault)
要更正这些问题,请执行以下操作:
而不是:
while(*it != b) it++;
adjList[a].erase(it);
做:
如果到达
end
时未找到元素b
,这将结束循环,if
子句将确保删除现有的迭代器。您没有测试迭代器是否指向adjList.end()
因此这可能是导致错误的原因,可能其中一个向量不包含您要查找的元素,因此您正在迭代结束。您最好使用std::find
。索引a
和b
在adjList
中有效吗?可能您在图中既没有b也没有a,迭代器经过adjList.end()。检查它是否正确!+end()使用删除擦除习惯用法。这将防止您犯愚蠢的错误,例如检查it
中的end
。您不是在测试迭代器是否指向adjList.end()
,因此这可能是segfaults的原因可能是其中一个向量不包含您要查找的元素,因此您正在迭代到末尾。您最好使用std::find
。索引a
和b
在adjList
中有效吗?可能您在图中既没有b也没有a,迭代器经过adjList.end()。检查它是否正确!+end()使用删除擦除习惯用法。这可以防止你犯愚蠢的错误,比如检查it
中的end
。我认为在这种情况下这并不重要。OP仅删除第一个引用。问题是删除结束迭代器,正如在评论中提到的。我按照你说的做了,仍然是一样的。也许是数组的问题。不是数组中的向量仅仅使用调试器怎么样?或者至少提供更多信息。我们甚至不知道它是一个数组还是一个向量……是的,我把它移到了某个IDE中,它显示出当它崩溃时,it
里面什么都没有,问题是我不知道@nidhoegger为什么我认为在这种情况下这不重要。OP仅删除第一个引用。问题是删除结束迭代器,正如在评论中提到的。我按照你说的做了,仍然是一样的。也许是数组的问题。不是数组中的向量仅仅使用调试器怎么样?或者至少提供更多信息。我们甚至不知道它是一个数组还是一个向量……是的,我把它移到了某个IDE中,当它崩溃时,它显示出它里面什么都没有,问题是我不知道为什么@Nidhoegger
while(it != adjList[a].end() && *it != b) it++;
if (it != adjList[a].end()) adjList[a].erase(it);