为什么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)
方法,它调用一些重新分配方法。之后,索引向量会自动重新分配,其中所有指针都指向另一个内存块。这就是为什么auto-it迭代器不能也不能进行比较而不递增,因为它指向错误的位置会变得无效。
感谢您的评论。事实证明,在问题发生的那一刻,我实际上是在对我迭代的同一个向量进行推回。当然,这会使迭代器失效。因此,问题出现在糟糕的数据组织和糟糕的编码风格中。我现在正在查看您的评论,现在我明白我的代码非常糟糕。谢谢你这么说。我也没有把整个代码放在评审中,因为我认为这已经足够了,但我确信我至少可以证明这是一个类,它有一些成员。并揭示更多结构。再次为此感到抱歉。我想我可能需要想出一些其他的数据结构,也许在内部算法完成之前不进行任何动态重新定位。另外,我知道0和1的索引是蹩脚的。我只是在做一个课程任务,这个任务在txt文件中,有基于1的索引。
是的,d和iter用于断点
相关文章:
- GlobalAlloc而不是其他分配方法
- 是否可以使用其他变量为变量分配值,而无需在 C++ 中更改其值?
- 有没有其他方法可以将地址分配给指针变量
- 当 lambda 函数必须访问其他成员时,如何将该函数分配给结构成员
- 在打印出动态分配的数组中的前两个数字时遇到问题,其他数字工作正常
- 使用分配给其他进程的内存
- 如果您称为destructor并将分配的内存再次用于其他对象,会发生什么
- 将结构的枚举传递给其他功能并分配值
- 将指针移动到其他位置后删除分配的内存
- 是否可以使用运算符new从堆以外的其他位置进行分配
- 当使用运算符 new 更改为其他内存的指向已分配内存的 ptr 时会发生什么
- 使用全局变量作为在其他源文件中分配的函数的参数
- 为什么std::vector迭代器在重新分配其他向量时无效
- c++在构造函数中使用指向其他方法的指针分配方法:我做错了什么?
- 在C/ c++中,链表只有头指针分配在堆栈中,其他节点分配在堆中.这可能导致内存泄漏
- 为什么检查分配操作的结果有效,但不能与其他条件相结合
- 在c++中分配动态数组的其他成员
- 正确删除std::列表中分配给其他地方的指针
- 对内存分配和构造函数的调用是否可以与执行"new"表达式所需的其他操作交错?
- 删除std::lock_guard相对于其他堆栈分配对象的顺序/速度