C++:访问 unordered_map 中的数据时出现段错误以进行设置
C++: segfault when accessing data in unordered_map to set
我定义了一个简单的结构 EdgeList,它只是一个 unordered_map
将字符串键与 set
个字符串相关联。
class EdgeList{
private:
std::unordered_map<std::string,std::set<std::string>> map;
public:
EdgeList(){};
void insert(std::string key,std::string item);
std::set<std::string> operator[](std::string key);
};
void EdgeList::insert(std::string key,std::string item)
{
if(map.count(key)==0) //key not already in map
{
std::set<string> newset;
map.emplace(key,newset);
}
map[key].insert(item);
}
std::set<string> EdgeList::operator[](string key){
return map[key];
}
EdgeList::insert
只是检查键是否已经存在于 unordered_map
中(如果不存在则创建一个新集合)并将该项目插入关联的集合中。 EdgeList::operator[]
returns 与输入键关联的集合。
这一切都很简单,但是当我尝试访问 EdgeList
中的数据时出现了问题。当我尝试
之类的东西时,我总是遇到神秘的段错误
EdgeList el;
//populate el
string KeyInEdgeList;
for(auto it=el[KeyInEdgeList].begin();it!=el[KeyInEdgeList].end();++it)
{
std::cout << *it << std::endl;
}
可能发生了什么? class 定义有误吗?出于某种原因我不能使用迭代器吗?我已经无计可施了,这应该不复杂。
您的 operator[]
return 值:
std::set<std::string> operator[](std::string key);
^^^^^^^^^^^^^^^^^^^^^
也就是说,每次调用此函数时,都会从底层映射中复制一个新的 std::set
,然后在表达式末尾销毁它。换句话说:
for(auto it=el[KeyInEdgeList].begin();it!=el[KeyInEdgeList].end();++it)
// |--- 1st set ---| |--- 2nd set ---|
那是两个 不同的 set
,当您实际解除对迭代器的引用时,它们都会被销毁。在 for
循环体内,您有一个悬空引用。
你想要做的是让你的 operator[]
return 成为参考,然后无论如何,使用基于范围的 for:
for (std::string const& elem : el[KeyInEdgeList]) { ... }
我定义了一个简单的结构 EdgeList,它只是一个 unordered_map
将字符串键与 set
个字符串相关联。
class EdgeList{
private:
std::unordered_map<std::string,std::set<std::string>> map;
public:
EdgeList(){};
void insert(std::string key,std::string item);
std::set<std::string> operator[](std::string key);
};
void EdgeList::insert(std::string key,std::string item)
{
if(map.count(key)==0) //key not already in map
{
std::set<string> newset;
map.emplace(key,newset);
}
map[key].insert(item);
}
std::set<string> EdgeList::operator[](string key){
return map[key];
}
EdgeList::insert
只是检查键是否已经存在于 unordered_map
中(如果不存在则创建一个新集合)并将该项目插入关联的集合中。 EdgeList::operator[]
returns 与输入键关联的集合。
这一切都很简单,但是当我尝试访问 EdgeList
中的数据时出现了问题。当我尝试
EdgeList el;
//populate el
string KeyInEdgeList;
for(auto it=el[KeyInEdgeList].begin();it!=el[KeyInEdgeList].end();++it)
{
std::cout << *it << std::endl;
}
可能发生了什么? class 定义有误吗?出于某种原因我不能使用迭代器吗?我已经无计可施了,这应该不复杂。
您的 operator[]
return 值:
std::set<std::string> operator[](std::string key);
^^^^^^^^^^^^^^^^^^^^^
也就是说,每次调用此函数时,都会从底层映射中复制一个新的 std::set
,然后在表达式末尾销毁它。换句话说:
for(auto it=el[KeyInEdgeList].begin();it!=el[KeyInEdgeList].end();++it)
// |--- 1st set ---| |--- 2nd set ---|
那是两个 不同的 set
,当您实际解除对迭代器的引用时,它们都会被销毁。在 for
循环体内,您有一个悬空引用。
你想要做的是让你的 operator[]
return 成为参考,然后无论如何,使用基于范围的 for:
for (std::string const& elem : el[KeyInEdgeList]) { ... }