繁体   English   中英

向量迭代器不兼容

[英]vector iterators incompatible

我目前正在为 C++ 开发一个图形库,现在卡在了运行时调试模式下出现断言错误的地方。 我还在这里查看了关于 SO 的其他一些问题,但没有一个问题和答案能引导我找到解决方案。 在阅读了一些论坛之后,我的印象是发生此错误是因为一旦矢量内容发生更改,迭代器就会变得无效。 (例如在使用erase()时)但是正如您在我的代码中看到的那样,我没有修改向量,只是迭代。

错误在我用//ASSERTION标记的行中。 奇怪的是, neighbor_it没有指向(*vertex_it)->neighbors( ) 中的第一个 object ,而是指向0xfeeefeee 通过代码进行调试时,我可以清楚地看到邻居向量至少包含一项。 不应该neighbor_it指向此向量中的第一个 object 吗?

更多信息: 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()现在返回一个迭代器,指向它从中删除边的向量中的下一个 object。 此外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()调用临时的object之后被处理掉了,得到的迭代器指向垃圾。

我猜想remove_edge修改了neighbor_it的底层容器,从而使其无效,但如果没有看到您的更多代码,我无法确定。

如果是这种情况,一种可能的解决方案是将迭代器返回到已删除元素之后的下一个元素,例如std::vector::erase所做的那样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM