c++ - 再次获取 std::map 会更改前一个迭代器

标签 c++ stdmap auto

我找不到任何类似的问题。 当我调用 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;
}

关于c++ - 再次获取 std::map 会更改前一个迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62039880/

相关文章:

c++ - 未使用的变量警告与自动变量不同

c++ - 完美转发到数据成员的成员函数?

c++ - 允许宏内的初始化程序列表

C++:std::map、查找循环、算法

c++ - map<string, string> 如何在这个 map 中插入数据?

c++ - 放置到 std::map 的 std::map

c++ - 未评估的操作数和自动返回类型

php - 为什么我在 C++ 和 PHP SHA256 哈希之间得到不同的结果?

C++ 问题 : 'break' within nested for loops not working as expected?

c++ - 如何使用初始化列表构造 std::array 对象?