C ++:访问unordered_map中的数据时出现段错误以设置

Posted

技术标签:

【中文标题】C ++:访问unordered_map中的数据时出现段错误以设置【英文标题】:C++: segfault when accessing data in unordered_map to set 【发布时间】:2017-11-20 02:44:38 【问题描述】:

我定义了一个简单的结构 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[] 返回与输入键关联的集合。

这一切都很简单,但是当我尝试访问EdgeList 中的数据时出现了问题。当我尝试类似

的东西时,我不断收到神秘的段错误
EdgeList el;
//populate el
string KeyInEdgeList;

for(auto it=el[KeyInEdgeList].begin();it!=el[KeyInEdgeList].end();++it)

  std::cout << *it << std::endl;

可能会发生什么?类定义有错误吗?由于某种原因,我不能使用迭代器吗?我已经束手无策了,这应该不复杂。

【问题讨论】:

std::mapoperator[] creates a key if it doesn't exist,所以你在insert(string, string) 中的if 语句是多余的。出于同样的原因,在for 循环中,您正在使用operator[] 创建一个空集,然后尝试取消引用循环内空集上的迭代器。 【参考方案1】:

您的operator[] 返回一个值:

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 ---|

这是两个不同 sets,当你真正取消引用你的迭代器时,它们都会被销毁。在for 循环的主体中,您有一个悬空引用。

您想要做的是让您的 operator[] 返回一个引用,然后无论如何都使用基于范围的:

for (std::string const& elem : el[KeyInEdgeList])  ... 

【讨论】:

以上是关于C ++:访问unordered_map中的数据时出现段错误以设置的主要内容,如果未能解决你的问题,请参考以下文章

电脑C盘中,我删除程序时,出现无法删除,访问被拒绝现象,问,如何解决?

使用 unordered_map 向量的 C++ 图形,在访问时添加随机数据,如 graph[i][j]

动态数组分配仅返回所有索引中的最后一个元素 C

SQL server附加数据库时出错,提示说: 附加数据库时出错。有关详细信息,请单击“消息”列中的超链接。急

Cache的一致性问题

C# 将表单中的数据插入访问数据库