矢量迭代器不兼容
vector iterators incompatible
我目前正在为C++开发一个图库,现在遇到了在运行时调试模式下出现断言错误的问题。我还看了SO上的其他问题,但没有一个问题和答案能让我找到解决方案。在一些论坛上阅读后,我的印象是,发生这种错误是因为一旦向量内容发生变化,迭代器就会失效。(例如,当使用erase()
时)但正如您在我的代码中看到的,我并没有修改向量,只是迭代。
错误在我用//ASSERTION
标记的行中。奇怪的是,neighbor_it
没有指向(*vertex_it)->neighbors(
)中的第一个对象,而是指向0xfeeefeee
。当调试代码时,我可以清楚地看到邻居向量至少包含一个项。neighbor_it
不应该指向这个向量中的第一个对象吗?
有关更多信息:m_vertices
是图中所有顶点的向量,vertex::neighbors()
返回边的向量(其具有指向邻居/目标顶点的指针)。在这个方法中,我想删除所有指向某个顶点的边。如果找到并删除了相应的边,则返回true;如果没有指向p_vertex
的边,返回false。
bool graph::remove_edges_pointing_to( vertex* p_vertex )
{
bool res = false;
std::vector<vertex*>::iterator vertex_it = m_vertices.begin();
// iterate through all vertices
while( vertex_it != m_vertices.end() )
{
// iterator on first element of neighbors of vertex
std::vector<edge*>::iterator neighbor_it = (*vertex_it)->neighbors().begin();
// iterate through all successors of each vertex
while( neighbor_it != (*vertex_it)->neighbors().end() ) //ASSERTION
{
if( (*neighbor_it)->dest() == p_vertex )
{
if( (*vertex_it)->remove_edge( *neighbor_it ) )
{
res = true;
}
}
neighbor_it++;
}
vertex_it++;
}
return res;
}
编辑:(解决方案)
好的,这是我的新代码,它可以正常工作。remove_edge()
现在将迭代器返回到它从中移除边的向量中的下一个对象。此外,neighbors()
现在向相应向量返回引用。
bool graph::remove_edges_pointing_to( vertex* p_vertex )
{
bool res = false;
std::vector<vertex*>::iterator vertex_it = m_vertices.begin();
// iterate through all vertices
while( vertex_it != m_vertices.end() )
{
// iterator on first element of neighbors of vertex
std::vector<edge*>::iterator neighbor_it = (*vertex_it)->neighbors().begin();
// iterate through all successors of each vertex
while( neighbor_it != (*vertex_it)->neighbors().end() )
{
if( (*neighbor_it)->dest() == p_vertex )
{
neighbor_it = (*vertex_it)->remove_edge( *neighbor_it );
res = true;
}
else
{
neighbor_it++;
}
}
vertex_it++;
}
return res;
}
再次感谢您的回答!:)
我的猜测是,在您提供的上下文有限的情况下,neighbours()
返回std::vector<edge*>
的副本,而不是引用,即std::vector<edge*>&
。所以begin()
调用后临时对象被处理掉,得到的迭代器指向垃圾。
我猜remove_edge
修改了neighbor_it
的底层容器,从而使其无效,但如果没有看到更多的代码,我就无法确定。
如果是这种情况,一个可能的解决方案是将迭代器返回到删除的元素之后的下一个元素,例如std::vector::erase
。
- 不明白迭代器,引用和指针失效,一个例子
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 为什么 min_element() 返回最小元素的索引,而不是迭代器?
- 我从 std::set 得到const_iterator而不是迭代器
- 为什么向量的.at()成员函数返回引用而不是迭代器
- 如果我有一个指向矢量元素的指针,而不是迭代器,如何删除它?
- 对于使用 C 样式指针矢量化的循环,但不使用迭代器
- 使用循环(而不是迭代器)从向量中删除指针
- 将指针而不是迭代器传递到std ::复制
- 如何在不使用迭代器的情况下在 C++ 中打印地图
- C++模板不接受迭代器
- 容器不可知迭代器参数
- 为什么 void* 不是迭代器类型?
- 如何在不使用迭代器的情况下访问任何向量的第 i 个元素
- 为什么在达到容量后在向量中插入时,C++不处理迭代器?
- 我可以用cout而不是迭代器循环打印STL映射吗?
- 为什么 std::bitset 不附带迭代器?
- 字符串::擦除不接受迭代器?
- 是否有一个标准容器允许在不使迭代器无效的情况下插入元素