C++地图上的循环没有检测到地图末端的变化
C++ loop on map not detecting change of map`s end
我在循环遍历地图(std::map)时遇到问题。
在我的循环中,有一个对函数的调用,该函数有时(并非总是)擦除同一映射的元素。使用此函数后,有一些代码使用此地图信息中的一些作为输入。
在此功能擦除任何元素后,我没有遇到任何问题,除了在擦除地图最后一个元素的独特情况下。
我的循环不明白地图的最后一个元素与它开始运行时不同,并且会尝试对不存在的元素进行操作,从而造成崩溃。
在我看来,对循环描述的 myMap.end() 调用无法使用映射的新 end() 更新自身。
下面列出了代码的相关部分:
for(std::map<int, ConnectionInfo>::iterator kv = myMap.begin(); kv != myMap.end(); ++kv) {
int thisConnectionID=kv->first; //This is where I get garbage when the loop enters when it shouldnt;
ConnectionInfo currentConnectionInfo=kv->second; //This is where I get garbage when the loop enters when it shouldnt;
status=eraseSomeMapElementsIfNecessary(thisConnectionID,currentConnectionInfo.DownPacket); //this function might erase elements on myMap. This generates no problems afterwards, except when the end element of myMap is erased
... //Next parts of the code make no further usage of myMaps, so I just hid it not to pollute the code
}
我的解释是kv != myMap.end()
无法理解内部循环正在更改(擦除)myMap 的最后一个元素(结束)吗?
在这种情况下,如何解决此问题?
还是我的解释是错误的,解决方案与我之前所说的无关?
感谢您的帮助!
使用可能删除元素迭代映射时的常用习惯用语是:
for(auto it = map.begin(); it != map.end(); ) {
if ( *it == /*is to delete*/ ) {
it = map.erase(it);
}
else
++it;
}
如果您的擦除某些地图元素如果必要可能会擦除正在迭代的地图中的一些随机值,那么这肯定会引起问题。如果it
引用的元素被擦除,则该元素将变为无效,则it
递增++it
也是无效的。
问题实际上只在于it
迭代器,如果擦除SomeMapElementsIfNecessary擦除它然后使用它 - 你有未定义的行为(UB)。因此,解决方案是传递当前迭代器以擦除SomeMapElementsIfNeed,并从中返回下一个迭代器以进行迭代:
it = eraseSomeMapElementsIfNecessary(it);
我示例中的 for 循环的主体应该在您的 eraseSomeMapElementsIf Required 函数中。至少这是一个解决方案。
在此功能擦除任何元素后,我没有遇到任何问题,除了在擦除地图最后一个元素的独特情况下。
擦除任何容器中的元素都会使该元素的迭代器失效。之后,递增无效的迭代器。
在删除迭代器所指向的元素之前,应递增迭代器。
如果您不知道在循环中运行的哪些元素会擦除,则假定所有迭代器都无效。
也许这两个链接会有所帮助:
- 如何使用迭代器删除 std::map 的元素?
- https://stackoverflow.com/a/8234813/3464942
基本上,这一切都归结为,您必须在迭代器失效之前对其进行更新。
在擦除当前迭代器之前,您必须保留下一个迭代器;因为删除元素后当前迭代器将无效。
auto nextit = it+1;
map.erase(it);
it = nextit;
- 为什么不;名字在地图上是按顺序排列的吗
- 使用CMake检测支持的C++标准
- 基于多个条件处理地图中的所有元素
- 当套接字连接断开时检测C/C++Unix
- 在C++中将矢量转换为嵌套地图
- C/C++预处理器是否可以检测一些编译器选项
- WMI检测进程创建事件-c++
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 下面是我为检测链接列表中的循环而制作的代码
- 落砂模拟碰撞检测C++和SFML
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么C++编译器没有检测到正确声明的类?
- 检测win32服务创建和删除的最佳方法
- 替换基于地图的所有引用
- 正在LLVM中检测整数比较条件
- 如何区分地图中的 0 和 false?
- 地图计数确实很重要,或者只是检查是否存在
- 如何在鼠标挂钩过程中检测拖动
- 如何在地图迭代器中检测最后一个元素
- C++地图上的循环没有检测到地图末端的变化