再次获得 std::map 会更改之前的迭代器
Getting again a std::map changes the previous iterator
我找不到任何类似的问题。 当我调用getMap的那一刻,以前的迭代器似乎发生了变化:
//IF I COMMENT THE EVIL PRINT, THE PROBLEM DOES NOT OCCUR
std::cout << "EVIL PRINT" << std::endl;
Something something;
auto mapElement = something.getTheMap().find("A");
std::cout << "Before: " << mapElement->first << std::endl;
something.getTheMap();
std::cout << "After: " << mapElement->first << std::endl << std::endl;
/****************************************************************************************/
//WITH SHARED POINTERS, THE EVIL PRINT IS NOT NECCESARY TO MAKE THE PROBLEM OCCUR
std::shared_ptr<Something> somePtr;
auto mapElement2 = something.getTheMap().find("A");
std::cout << "Before: " << mapElement2->first << std::endl;
something.getTheMap();
std::cout << "After: " << mapElement2->first << std::endl << std::endl;
输出:
EVIL PRINT
Before: A
After: B
Before: A
After: B
完整的代码可在此处运行 https://coliru.stacked-crooked.com/a/66b48636a476ddb7
这是通缉行为吗?发生了什么事情?
您在问题中没有包括最重要的部分,即
std::map <std::string, int> getTheMap() {
return theMap;
}
getTheMap
返回一个副本,因此getTheMap().find("A");
将迭代器返回到临时对象(在调用完成后停止存在对象(。因此,该迭代器
引用不再存在的对象,它是一个悬空的迭代器。取消引用它(就像你对mapElement->first
所做的那样(会调用未定义的行为
最惯用的解决方法是让getTheMap
返回引用,例如:
std::map <std::string, int>& getTheMap() {
return theMap;
}
您有未定义的行为,因为您在映射的生命周期之外引用映射。
getTheMap()
按值返回地图,这意味着您将获得原始地图的副本。您永远不会将此副本保存在任何位置,因此迭代器在创建后会立即晃来晃去。
Something something;
auto mapElement = something.getTheMap().find("A"); //temporary map used here
// temporary map is gone and mapElement is invalid
根据你想要的,你可以通过引用返回地图(这将允许从外部修改内部地图(:
std::map <std::string, int>& getTheMap() {
return theMap;
}
或者保存复制映射以确保它在使用迭代器时存在
auto map = something.getTheMap();
auto mapElement = map.find("A");
相关文章:
- 再次获得 std::map 会更改之前的迭代器
- 使用 map<char,strring> 的迭代器返回指针 map<char,strring>*
- 创建可以遍历 std::map 值的通用模板迭代器的最简单方法是什么?
- 从基于迭代器的for循环转换后,如何在map::find()中调用方法
- 为什么我不能在 c++ 中"map"的迭代器中使用"+1"?
- Map中的(字符串的)向量迭代器
- 访问基于范围的循环(如for_each)中的std::map迭代器
- map<int,int>的*迭代器是什么?它不是pair<int,int>
- std::map 擦除 - 将迭代器传递给错误的映射
- C++ Map erase(),迭代器打印 erased 元素
- 由于从 std::map 派生的类中的 std::map 迭代器导致的内存错误
- C++ std::map 和 std::set 擦除复制值,从而使迭代器失效
- 如果迭代器的迭代器永远不会无效,则是STD :: MAP访问线程安全
- SIGBUS 尝试递增 std::map 迭代器时
- C 迭代器从Typedef std :: Map作为模板参数声明
- std::map 线程安全和迭代器失效
- 为什么要对 map::find 应用不存在的键将返回一个C++中第一个值映射大小的迭代器
- 为 map<T1、T2> 迭代器创建模板函数
- std::map<>::迭代器错误
- std :: map :: size()与迭代器不同