(Примечание для будущих читателей: Ошибка, что не удивительно, в моем коде, а не STD :: _ Rb_tree_rebalance_for_erase())вина Сегментация в станд функции станд :: _ Rb_tree_rebalance_for_erase()
Я несколько новых для программирования и я не уверен, как бороться с ошибкой сегментации, которая, как представляется, поступает из функции std. Надеюсь, я делаю что-то глупое (т. Е. Неправильно использую контейнер), потому что я понятия не имею, как это исправить.
Точная ошибка
Программа получила сигнал EXC_BAD_ACCESS, не удалось получить доступ к памяти.
Причина: KERN_INVALID_ADDRESS по адресу: 0x000000000000000c
0x00007fff8062b144 в станд :: _ Rb_tree_rebalance_for_erase()
(GDB) трассировку
# 0 0x00007fff8062b144 в станд :: _ Rb_tree_rebalance_for_erase()
# 1 0x000000010000e593 в моделировании :: runEpidSim (это = 0x7fff5fbfcb20) в stl_tree.h: 1263
# 2 0x0000000100016078 в основной() в main.cpp: 43
функция, которая выходит успешно как раз перед обновит ошибки сегментации содержимое двух контейнеров. Один из них - boost::unordered_multimap
под названием carriage
; он содержит один или несколько объектов struct Infection
. Другой контейнер имеет тип std::multiset< Event, std::less< Event > > EventPQ
под названием ce
.
void Host::recover(int s, double recoverTime, EventPQ & ce) {
// Clearing all serotypes in carriage
// and their associated recovery events in ce
// and then updating susceptibility to each serotype
double oldRecTime;
int z;
for (InfectionMap::iterator itr = carriage.begin(); itr != carriage.end(); itr++) {
z = itr->first;
oldRecTime = (itr->second).recT;
EventPQ::iterator epqItr = ce.find(Event(oldRecTime));
assert(epqItr != ce.end());
ce.erase(epqItr);
immune[ z ]++;
}
carriage.clear();
calcSusc(); // a function that edits an array
cout << "Done with sync_recovery event." << endl;
}
Последняя cout <<
линия появляется непосредственно перед вине SEG.
Моя идея до сих пор заключается в том, что после этой функции выполняется попытка перебалансировки на ce
, но я не уверен, что перебалансировка будет неудачной.
Update
Я подтвердил вину сегм уходит (хотя программа тут же падает и по другим причинам), когда я удаляю ce.erase(epqItr);
. Я могу успешно удалить события в другом месте в коде; код, который я использую для стирания элементов в ce
, равен идентичным тому, что здесь.
обратной трассировке без оптимизации (спасибо, БДК) показывает намного больше информации:
Программа получила сигнал EXC_BAD_ACCESS, не удалось получить доступ к памяти.
Причина: KERN_INVALID_ADDRESS по адресу: 0x000000000000000c
0x00007fff8062b144 в станд :: _ Rb_tree_rebalance_for_erase()
(GDB) трассировку
# 0 0x00007fff8062b144 в станд :: _ Rb_tree_rebalance_for_erase()
# 1 0x00000001000053d2 в станд :: _ Rb_tree, станд: : less,> std :: allocator> :: erase (this = 0x7fff5fbfdfe8, __position = {_ M_node = 0x10107cb50}) at> stl_tree.h: 1263
# 2 0x0000000100005417 в std :: multiset, std :: allocator> :: erase (this = 0x7fff5fbfdfe8, __position = {_ M_node = 0x10107cb50}) в stl_multiset.ч: 346 # 3 0x000000010000ba71 в моделировании :: runEpidSim (это = 0x7fff5fbfcb40) при Simulation.cpp: 426
# 4 0x000000010001fb31 в главной() в main.cpp: 43
Если Xcode не читает номера строк неправильно, единственный stl_tree.h на моем жестком диске пуст в строке 1263.
Несколько человек попросили увидеть функцию, которая вызывает восстановление. Это немного сложнее:
struct updateRecovery{
updateRecovery(int s, double t, EventPQ & ce) : s_(s), t_(t), ce_(ce) {}
void operator() (boost::shared_ptr<Host> ptr) {
ptr->recover(s_, t_, ce_);
}
private:
int s_;
double t_;
EventPQ & ce_;
};
// allHosts is a boost::multiindex container of boost::shared_ptr<Host>
// currentEvents is the EventPQ container
// it is an iterator to a specific member of allHosts
allHosts.modify(it, updateRecovery(s, t, currentEvents));
cout << "done with recovery" << endl;
Последние cout
отпечатки. Ранее код работал без этой конкретной функции восстановления.
Noah Roberts правильно указал, что проблема в Simulation.cpp, строка 426. Перейти ниже для неловкого решения.
Что находится на stl_tree.h: 1263? –
Единственный stl_tree.h, который отображается на моем жестком диске (также единственный файл, содержащий «_Rb_tree_rebalance_for_erase» на моем HD), * * * в строке 1263 (?!). Я использую gcc 4.2.1 (Apple build 5646) на i686-apple-darwin10. Функция rebalance_for_erase определена в строках 299-429. – Sarah
Если вы поместили cout в вызывающий код сразу после вызова Host :: recover, распечатывается ли это? Кроме того, попробуйте выполнить компиляцию со всеми оптимизациями и отключением вложения, и вы можете получить более полезную трассировку стека – bdk