Sar*_*rah 1 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
};
Run Code Online (Sandbox Code Playgroud)
这些结构保存在一个特殊的结构中,InfectionMap:
typedef boost::unordered_multimap< int, Infection > InfectionMap;
Run Code Online (Sandbox Code Playgroud)
班上的每个成员Host都有InfectionMap carriage.恢复时间和关联的主机标识符保存在优先级队列中.当s在特定主机中的特定应变的模拟中出现预定的恢复事件时,程序搜索carriage该主机以找到与恢复时间()匹配的Infection那些.(对于那些不值得进入的原因,它不是作为权宜之计,我使用为重点,以;应变更为有用的,一脉相承合并感染是可能的.)recTdouble recoverTimerecTInfectionMaps
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 );
}
}
Run Code Online (Sandbox Code Playgroud)
我在上面指定的行上收到"程序接收信号EXC_BAD_ACCESS,无法访问内存.原因:地址处的KERN_INVALID_ADDRESS ...".recoverTime很好,并且assert(...)代码中没有跳闸.
正如我所说,在成千上万次成功的恢复事件之后,这个seg故障就会"随机"出现.
你怎么去弄清楚发生了什么?我喜欢关于可能出错的问题以及如何进一步调查问题的想法.
更新
我在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 );
}
}
Run Code Online (Sandbox Code Playgroud)
现在(*it).first,在数千次成功恢复之后,EXC_BAD_ACCESS错误现在出现在呼叫中.任何人都可以给我提示如何弄清楚这个问题是如何产生的?我正在尝试使用gdb.来自回溯的帧0读取
Host.cpp中的主机:: recover中的#0 0x0000000100001d50(此= 0x100530d80,s = 0,recoverTime = 635.91148029170529):317"
我不确定我能在这里提取哪些有用的信息.
更新2
我添加了一个break;后carriage.erase(it).这有效.
如果我错了,请纠正我,但我敢打赌,删除无序多图中的项会使指向它的所有迭代器无效.试试"it = carriage.erase(it)".你也必须做一些关于ret的事情.
更新以回复您的最新更新:
在调用"carriage.erase(it)"之后突破循环的原因修复了这个错误是因为你停止尝试访问一个已删除的迭代器.