在 C++ 中将 getter 用于 unordered_map 会创建大小为 8 的无效读取
Using getter for an unordered_map in c++ creates an invalid read of size 8
我正在尝试对字段 std::unordered_map<std::string, User *> userMap
使用 getter 以在其中查找用户。
我做得太累了:
std::unordered_map<std::string, User *>::const_iterator found = getUserMap().find(userName);
但 valgrind 检测到大小为 8 的无效读取。
但是,当我这样做时:
std::unordered_map<std::string, User *> tmpUserMap = getUserMap();
std::unordered_map<std::string, User *>::const_iterator found = tmpUserMap.find(userName);
无效读取消失了。
getter 是标准 getter:
std::unordered_map<std::string, User *> Session::getUserMap() const{
return userMap;
}
如果需要,我可以提供 valgrind 数据,我在 clion 编辑器上使用 c++11。
getUserMap
returns userMap
的 副本 。这意味着您获得的迭代器只能与所述副本一起使用。
因此,当您存储副本然后将迭代器与它一起使用时,一切正常。
当您多次调用 getUserMap
时,您会获得地图的 不同 和临时副本。您不能使用从第一个副本(现在无效,因为它的映射是临时的)获得的迭代器来访问第二个副本。当您尝试时会出现未定义的行为,这就是您看到令人困惑的错误的原因。
这是按值返回的本质,它总是returns一个新对象而不是原始对象。如果你想直接读取 userMap
,那么考虑返回一个 const 引用来代替它:
std::unordered_map<std::string, User *> const& Session::getUserMap() const{
return userMap;
}
执行此操作时:
std::unordered_map<std::string, User *>::const_iterator found = getUserMap().find(userName);
您正在使用临时对象的方法find()
。因此,您得到的迭代器在语句执行后无效(参见the lifetime of temporary objects)。
在其他代码中,tmpUserMap
实际上不是一个临时对象,迭代器仍然可用,因为它的源还没有被销毁。
为什么在第一个片段集中得到一个临时对象?因为 getUserMap()
returns 按值会触发创建 userMap
.
的副本
我正在尝试对字段 std::unordered_map<std::string, User *> userMap
使用 getter 以在其中查找用户。
我做得太累了:
std::unordered_map<std::string, User *>::const_iterator found = getUserMap().find(userName);
但 valgrind 检测到大小为 8 的无效读取。 但是,当我这样做时:
std::unordered_map<std::string, User *> tmpUserMap = getUserMap();
std::unordered_map<std::string, User *>::const_iterator found = tmpUserMap.find(userName);
无效读取消失了。
getter 是标准 getter:
std::unordered_map<std::string, User *> Session::getUserMap() const{
return userMap;
}
如果需要,我可以提供 valgrind 数据,我在 clion 编辑器上使用 c++11。
getUserMap
returns userMap
的 副本 。这意味着您获得的迭代器只能与所述副本一起使用。
因此,当您存储副本然后将迭代器与它一起使用时,一切正常。
当您多次调用 getUserMap
时,您会获得地图的 不同 和临时副本。您不能使用从第一个副本(现在无效,因为它的映射是临时的)获得的迭代器来访问第二个副本。当您尝试时会出现未定义的行为,这就是您看到令人困惑的错误的原因。
这是按值返回的本质,它总是returns一个新对象而不是原始对象。如果你想直接读取 userMap
,那么考虑返回一个 const 引用来代替它:
std::unordered_map<std::string, User *> const& Session::getUserMap() const{
return userMap;
}
执行此操作时:
std::unordered_map<std::string, User *>::const_iterator found = getUserMap().find(userName);
您正在使用临时对象的方法find()
。因此,您得到的迭代器在语句执行后无效(参见the lifetime of temporary objects)。
在其他代码中,tmpUserMap
实际上不是一个临时对象,迭代器仍然可用,因为它的源还没有被销毁。
为什么在第一个片段集中得到一个临时对象?因为 getUserMap()
returns 按值会触发创建 userMap
.