(请注意未来的读者:不出所料,错误出现在我的代码中,而不是 std::_Rb_tree_rebalance_for_erase () )
我对编程有点陌生,不确定如何处理似乎来自 std 函数的分段错误。我希望我做了一些愚蠢的事情(即滥用容器),因为我不知道如何修复它。
精确的误差是
程序收到信号 EXC_BAD_ACCESS,无法访问内存。
原因:KERN_INVALID_ADDRESS,地址:0x000000000000000c
std::_Rb_tree_rebalance_for_erase () 中的 0x00007fff8062b144
(gdb) 回溯
#0 0x00007fff8062b144 在 std::_Rb_tree_rebalance_for_erase ()
#1 0x000000010000e593 在Simulation::runEpidSim (this=0x7fff5fbfcb20) at stl_tree.h:1263
#2 0x0000000100016078 在 main () 处 main.cpp:43
在分段错误之前成功退出的函数会更新两个容器的内容。一个是一个boost::unordered_multimap
called carriage
;它包含一个或多个struct Infection
对象。另一个容器的类型是std::multiset< Event, std::less< Event > > EventPQ
called 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 <<
该行出现在段故障之前。
到目前为止我的想法是正在尝试重新平衡ce
紧随此功能之后,但我不确定为什么重新平衡会失败。
Update
我已经确认当我删除时,段错误消失了(尽管程序因其他原因立即崩溃)ce.erase( epqItr );
。我能够在代码中的其他位置成功删除事件;我用来删除其中项目的代码ce
is 完全相同的到这里的东西。
回溯without优化(感谢,bdk)揭示了更多信息:
程序收到信号 EXC_BAD_ACCESS,无法访问内存。
原因:KERN_INVALID_ADDRESS,地址:0x000000000000000c
std::_Rb_tree_rebalance_for_erase () 中的 0x00007fff8062b144
(gdb) 回溯
#0 0x00007fff8062b144 在 std::_Rb_tree_rebalance_for_erase ()
#1 0x00000001000053d2 in std::_Rb_tree, std::less, > std::allocator >::erase (this=0x7fff5fbfdfe8, __position={_M_node = 0x10107cb50}) at > stl_tree.h:1263
#2 0x0000000100005417 in std::multiset, std::allocator >::erase (this=0x7fff5fbfdfe8, __position={_M_node = 0x10107cb50}) at stl_multiset.h:346
#3 0x000000010000ba71 在Simulation::runEpidSim (this=0x7fff5fbfcb40) 在Simulation.cpp:426
#4 0x000000010001fb31 在 main () 处 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 行。跳到下面查看令人尴尬的解决方案。