删除元素后 std::map::迭代器的有效性
Validity of std::map::iterator after erasing elements
我写了一个代码来解决以下问题: 我们有一个map<double,double>
,里面有(相对)大量的项目。我们希望合并相邻的项目,以减小地图的大小,尽可能降低一定的"损失因子"。
为此,我首先填充一个包含相邻迭代器和关联的损失因子的列表(假设每个列表元素都有以下类型:
struct myPair {
map<double,double>::iterator curr, next;
double loss;
myPair(map<double,double>::iterator c, map<double,double>::iterator n,
double l): curr(c), next(n), loss(l) {}
};
)。 这是按如下方式完成的:
for (map<double,double>::iterator it1 = myMap.begin(); it1 != --(myMap.end());
it1++) {
map<double,double>::iterator it2 = it1; it2++;
double l = computeLoss(it1,it2);
List.push(myPair(it1,it2,l));
}
然后,我找到对应于最低损失因子的列表元素,从map
中erase
相应的元素,并在map
中insert
一个新元素(合并curr
和next
的结果)。由于这也更改了next
之后或之前与元素对应的列表元素curr
因此我更新了相应的条目以及相关的损失因子。
(我没有详细介绍如何有效地实现上述内容,但基本上我正在结合双链表和堆)。
虽然erase
操作不应使程序的某些特定输入实例的其余迭代器无效,但我在尝试从map
中删除元素时正好得到double free or corruption
错误。
我试图跟踪这一点,当两个地图元素的first
和second
条目都非常接近时(更准确地说,当curr
和next
的first
非常接近时),似乎会发生这种情况。
奇怪的是,我在填充列表时放置了一个assert
,以确保在所有条目中curr
和next
是不同的,并且在删除元素的循环中assert
相同的。第二个失败了!
如果有人可以帮助我,我将不胜感激。
附言我很抱歉不是很精确,但我想尽可能降低细节。
更新:这是我从地图中删除元素的方式(非常简化的版本):
while (myMap.size() > MAX_SIZE) {
t = list.getMin();
/* compute the merged version ... let's call the result as (a,b) */
myMap.erase(t.curr);
myMap.erase(t.next);
myMap.insert(pair<double,double>(a,b));
/* update the adjacent entries */
}
myPair
中存储的迭代器在容器修改后保持无效。你应该避免这种技术。当您查看头文件时,可能会找到一些适合您任务的草稿?
正如其他人已经提到的,事实证明,使用 double
作为map
的密钥是有问题的。特别是在计算值时。
因此,我的解决方案是使用 std::multimap
而不是 map
(然后在填充地图后使用相同的键合并元素)。例如,即使a
非常接近t.curr
键和t.next
键或任何其他元素,也可以肯定的是,insert
操作会创建一个新元素,以便list
中没有现有iterator
指向该元素。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 列表的有效性在插入后开始迭代器
- 没有迭代器失效是否意味着推进迭代器的有效性?
- 螺纹安全与迭代器有效性
- 迭代器有效性
- 删除元素后 std::map::迭代器的有效性
- c++迭代器有效性问题
- std::vector<std::vector 的迭代器有效性<T>>
- STL列表:拼接迭代器有效性
- 通过插入保持std::list迭代器的有效性