c++ - 访问 boost::unordered_multimap 或结构时很少出现段错误

标签 c++ struct segmentation-fault

我在调试段错误时遇到问题。我很感激有关如何缩小问题范围的提示。

当迭代器试图访问结构 Infection 的元素时出现错误,定义为:

struct Infection {
public:
  explicit Infection( double it, double rt ) : infT( it ), recT( rt ) {}
  double infT; // infection start time
  double recT; // scheduled recovery time
};

这些结构保存在一个特殊的结构中,InfectionMap:

typedef boost::unordered_multimap< int, Infection > InfectionMap;

Host 类的每个成员都有一个InfectionMap carriage。恢复时间和关联的主机标识符保存在优先级队列中。当在特定主机中针对特定菌株 s 的模拟中出现计划恢复事件时,程序会搜索该主机的 carriage 以找到 InfectionrecT 与恢复时间匹配(double recoverTime)。 (由于一些不值得深入探讨的原因,使用 recT 作为 InfectionMap 的键对我来说并不方便;菌株 s更有用,并且有可能与同一毒株合并感染。)

assert( carriage.size() > 0 );
pair<InfectionMap::iterator,InfectionMap::iterator> ret = carriage.equal_range( s );
InfectionMap::iterator it;
for ( it = ret.first; it != ret.second; it++ ) {
  if ( ((*it).second).recT == recoverTime ) { // produces seg fault
    carriage.erase( it );
  }
}

我在上面指定的行中收到“程序收到信号 EXC_BAD_ACCESS,无法访问内存。原因:地址处的 KERN_INVALID_ADDRESS...”。 recoverTime 很好,代码中的 assert(...) 没有被触发。

正如我所说,此段错误在数千次成功恢复事件后“随机”出现。

您将如何着手弄清楚发生了什么?我很想知道可能出了什么问题,以及如何进一步调查该问题。


更新

我在 for 循环中添加了一个新的断言和一个检查:

assert( carriage.size() > 0 );
assert( carriage.count( s ) > 0 );
pair<InfectionMap::iterator,InfectionMap::iterator> ret = carriage.equal_range( s );
InfectionMap::iterator it;
cout << "carriage.count(" << s << ")=" << carriage.count(s) << endl;
for ( it = ret.first; it != ret.second; it++ ) {
  cout << "(*it).first=" << (*it).first << endl; // error here
  if ( ((*it).second).recT == recoverTime ) {
    carriage.erase( it );
  }
}

EXC_BAD_ACCESS 错误现在出现在 (*i​​t).first 调用中,在数千次成功恢复后再次出现。谁能给我一些提示,告诉我如何弄清楚这个问题是如何产生的?我正在尝试使用 gdb。回溯读取的第 0 帧

“#0 0x0000000100001d50 in Host::recover (this=0x100530d80, s=0, recoverTime=635.91148029170529) at Host.cpp:317”

我不确定我可以在这里提取哪些有用的信息。


更新 2

我在 carriage.erase(it) 之后添加了一个 break;。这行得通。

最佳答案

如果我错了请纠正我,但我敢打赌,在无序多重映射中删除一个项目会使指向它的所有迭代器失效。尝试“it = carriage.erase(it)”。您还必须对 ret 做一些事情。

更新以回复您的最新更新:

调用“carriage.erase(it)”修复错误后跳出循环的原因是因为您停止尝试访问已删除的迭代器。

关于c++ - 访问 boost::unordered_multimap 或结构时很少出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2861532/

相关文章:

C++/VS 2010 : Bug(s) occur only when running without a debugger

c++ - 根据对象类调用不同的方法

c++ - 在 pthread 中使用堆分配 >100MB 的 RAM

C 结构节点

c - 读取数据并将其输入到二维字符数组,以及 printf。在c中

c - 文本文件上的Strtok导致段错误

c++ - 为什么这个独立程序会出现段错误?

c - 如何在 C 中通过引用将结构数组传递给函数?

c - 删除/销毁功能逻辑(结构/尝试)

c++ - GTK+,如何将小部件更新到主循环中?