繁体   English   中英

为什么在重新分配其他向量时std :: vector迭代器无效?

[英]Why is std::vector iterator invalidation upon reallocation of other vector?

这与该主题的其他问题并不完全相同。 我只是偶然发现了一件非常奇怪的事情,无法了解这是怎么发生的。

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);
            }
        }

在此函数的中间,我迭代一个顶点的索引向量,偶尔将一些值推回另一个顶点的索引向量。

在运行此代码时,我已经开始收到错误消息“ Vector iterator not icrementable”。 我决定进行更仔细的调试,发现当我在此处执行一定数量的push_back vertex_a.edge_indices.push_back(current_index) ,并且向量的大小和容量均为19时,向量实现会调用_Reserve(1)方法,它调用一些reallocate方法。 之后,索引向量自动重新分配,其内部的所有指针都指向另一个内存块。 这就是为什么不能且也不将自动迭代器不进行递增的原因,因为指向无效位置的迭代器变得无效。

感谢您的意见。 事实证明,在发生问题的那一刻,我实际上是在对要迭代的向量进行推回。当然,这会使迭代器无效。 因此,问题出在不良的数据组织和不良的编码风格中。 我现在正在查看您的评论,现在我知道我的代码很糟糕。 感谢您指出。 我也没有将整个代码进行审查,因为认为这足够了,但是可以肯定的是,我至少可以证明它是一个类并且有一些成员。 并揭示更多的结构。 再次为此感到抱歉。 我认为我可能需要提出其他一些数据结构,也许在完成内部算法之前不进行任何动态重新分配。 我也知道0和1索引很la脚。 我正在做一个课程任务,该任务在txt文件中,并且具有基于1的索引。

是的,d和iter是断点

暂无
暂无

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

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