简体   繁体   English

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

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

That's not the exact same copy of other questions on the topic. 这与该主题的其他问题并不完全相同。 I've just stumbled into something really strange and can't get how this happened. 我只是偶然发现了一件非常奇怪的事情,无法了解这是怎么发生的。

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

In the middle of this function I'm iterating over indices vector of one vertex and occasionly push_back some values to the indices vector of other vertex. 在此函数的中间,我迭代一个顶点的索引向量,偶尔将一些值推回另一个顶点的索引向量。

While running this code , I've started to recieve error message "Vector iterator not icrementable". 在运行此代码时,我已经开始收到错误消息“ Vector iterator not icrementable”。 I've decided to debug closer and found that when I do certain amount of push_back s here vertex_a.edge_indices.push_back(current_index) , and both the size and the capacity of the vector is 19, the vector implementation calls _Reserve(1) method, which calls some reallocate method. 我决定进行更仔细的调试,发现当我在此处执行一定数量的push_back vertex_a.edge_indices.push_back(current_index) ,并且向量的大小和容量均为19时,向量实现会调用_Reserve(1)方法,它调用一些reallocate方法。 And after that the indices vector gets reallocated automaticly with all pointers inside of it pointing to the other memory block. 之后,索引向量自动重新分配,其内部的所有指针都指向另一个内存块。 That's why the auto it iterator can not be nor compared not incremented, because it becomes invalid pointing to some wrong place. 这就是为什么不能且也不将自动迭代器不进行递增的原因,因为指向无效位置的迭代器变得无效。

Thanks for your comments. 感谢您的意见。 It turned out that at the moment that the problem happens I'm actually pushing_back against the same vector I'm iterating in. And of course this invalidates iterators. 事实证明,在发生问题的那一刻,我实际上是在对要迭代的向量进行推回。当然,这会使迭代器无效。 So the problem occured to be in a bad data organization and bad coding style. 因此,问题出在不良的数据组织和不良的编码风格中。 I'm looking at your comments now and I understand now that my code is pretty bad. 我现在正在查看您的评论,现在我知道我的代码很糟糕。 Thanks for indicating that. 感谢您指出。 I've also didnt put the whole code for review, because thought it would be enough but sure I could at least show that it is a class and it has some members. 我也没有将整个代码进行审查,因为认为这足够了,但是可以肯定的是,我至少可以证明它是一个类并且有一些成员。 And reveal more structure. 并揭示更多的结构。 Again sorry for that. 再次为此感到抱歉。 I think I'd probably need to come up with some other data structure, maybe not doing any dynamic reallocations until the inner algorithm is done. 我认为我可能需要提出其他一些数据结构,也许在完成内部算法之前不进行任何动态重新分配。 Also the 0 and 1 indexing is lame, I know that. 我也知道0和1索引很la脚。 I'm just doing a course task and the task is in txt file and has 1-based indexing. 我正在做一个课程任务,该任务在txt文件中,并且具有基于1的索引。

And yes, d and iter were for breakpoints 是的,d和iter是断点

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

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