У меня проблемы с отладкой ошибки сегментации. Буду признателен за советы о том, как сузить проблему.
Ошибка появляется, когда итератор пытается получить доступ к элементу структуры 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
этого хоста, чтобы найти Infection
, recT
которого соответствует времени восстановления (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 at address ...» в строке, указанной выше. RecoveryTime в порядке, и assert(...)
в коде не отключается.
Как я уже сказал, эта ошибка сегмента появляется «случайно» после тысяч успешных событий восстановления.
Как бы вы поняли, что происходит? Мне бы хотелось получить представление о том, что может быть не так, и о том, как я могу продолжить изучение проблемы.
Обновление
Я добавил новый 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 теперь появляется при вызове (*it).first
, снова после многих тысяч успешных восстановлений. Кто-нибудь может дать мне советы, как выяснить, как возникает эта проблема? Я пытаюсь использовать GDB. Кадр 0 из следа читает
"# 0 0x0000000100001d50 в Host :: restore (this = 0x100530d80, s = 0, recoverTime = 635.91148029170529) в Host.cpp: 317"
Я не уверен, какую полезную информацию я могу извлечь здесь.
Обновление 2
Я добавил break;
после carriage.erase(it)
. Это работает.