std 函数 std::_Rb_tree_rebalance_for_erase () 中的分段错误 [英] Segmentation fault in std function std::_Rb_tree_rebalance_for_erase ()

查看:28
本文介绍了std 函数 std::_Rb_tree_rebalance_for_erase () 中的分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(任何未来的读者请注意:毫无疑问,错误在我的代码中,而不是 std::_Rb_tree_rebalance_for_erase () )

(Note to any future readers: The error, unsurprisingly, is in my code and not std::_Rb_tree_rebalance_for_erase () )

我对编程有点陌生,不确定如何处理似乎来自 std 函数的分段错误.我希望我在做一些愚蠢的事情(即滥用容器),因为我不知道如何解决它.

I'm somewhat new to programming and am unsure how to deal with a segmentation fault that appears to be coming from a std function. I hope I'm doing something stupid (i.e., misusing a container), because I have no idea how to fix it.

准确的误差是

程序收到信号EXC_BAD_ACCESS,无法访问内存.
原因:KERN_INVALID_ADDRESS 地址:0x000000000000000c
0x00007fff8062b144 在 std::_Rb_tree_rebalance_for_erase ()
(gdb) 回溯
#0 0x00007fff8062b144 在 std::_Rb_tree_rebalance_for_erase ()
#1 0x000000010000e593 in Simulation::runEpidSim (this=0x7fff5fbfcb20) at stl_tree.h:1263
#2 0x0000000100016078 in main() at main.cpp:43

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000000000000c
0x00007fff8062b144 in std::_Rb_tree_rebalance_for_erase ()
(gdb) backtrace
#0 0x00007fff8062b144 in std::_Rb_tree_rebalance_for_erase ()
#1 0x000000010000e593 in Simulation::runEpidSim (this=0x7fff5fbfcb20) at stl_tree.h:1263
#2 0x0000000100016078 in main () at main.cpp:43

在分段错误更新两个容器的内容之前成功退出的函数.一种是名为carriageboost::unordered_multimap;它包含一个或多个 struct Infection 对象.另一个容器的类型是 std::multiset<;事件,std::less<事件 > > EventPQ 称为 ce.

The function that exits successfully just before the segmentation fault updates the contents of two containers. One is a boost::unordered_multimap called carriage; it contains one or more struct Infection objects. The other container is of type 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 << 行出现在段错误之前.

The last cout << line appears immediately before the seg fault.

到目前为止,我的想法是在此函数之后立即在 ce 上尝试重新平衡,但我不确定重新平衡为什么会失败.

My idea so far is that the rebalancing is being attempted on ce immediately after this function, but I am unsure why the rebalancing would be failing.

更新

当我删除 ce.erase(epqItr); 时,我已确认 seg 故障消失(尽管程序随后因其他原因立即崩溃).我能够在代码的另一个位置成功删除事件;我在那里用来擦除 ce 中的项目的代码与此处的内容相同.

I've confirmed the seg fault goes away (though the program then immediately crashes for other reasons) when I remove ce.erase( epqItr );. I am able to remove events successfully in another place in the code; the code I use there to erase items in ce is identical to what's here.

回溯没有优化(感谢,bdk)揭示了更多信息:

Backtracing without optimization (thanks, bdk) reveals much more information:

程序收到信号EXC_BAD_ACCESS,无法访问内存.
原因:KERN_INVALID_ADDRESS 地址:0x000000000000000c
0x00007fff8062b144 在 std::_Rb_tree_rebalance_for_erase ()
(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 in Simulation::runEpidSim (this=0x7fff5fbfcb40) at Simulation.cpp:426
#4 0x000000010001fb31 in main() at main.cpp:43

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x000000000000000c
0x00007fff8062b144 in std::_Rb_tree_rebalance_for_erase ()
(gdb) backtrace
#0 0x00007fff8062b144 in 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 in Simulation::runEpidSim (this=0x7fff5fbfcb40) at Simulation.cpp:426
#4 0x000000010001fb31 in main () at main.cpp:43

除非 Xcode 读取行号错误,否则我硬盘中唯一的 stl_tree.h 在第 1263 行是空白的.

Unless Xcode is reading line numbers wrong, the only stl_tree.h in my hard drive is blank on line 1263.

有几个人要求查看调用recover的函数.有点复杂:

A few people asked to see the function that calls recover. It's a bit complicated:

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 打印出来.该代码以前在没有此特定版本的恢复功能的情况下工作.

The last cout prints. The code worked before without this particular version of the recovery function.

Noah Roberts 正确指出问题出在 Simulation.cpp 的第 426 行.跳转到下面的尴尬解决方案.

Noah Roberts correctly pointed out that the problem is at Simulation.cpp, line 426. Jump below for embarrassing solution.

推荐答案

可能你在调用恢复时持有一个迭代器进入 ce.如果恢复碰巧删除了该项目,则迭代器将失效,并且将来的任何使用(例如尝试擦除它)都可能导致段错误.

Possibly you're holding onto an iterator into ce across the call to recover. If recover happens to remove that item the iterator will be invalidated and any future use (say an attempt to erase it) could result in a seg fault.

如果我们能看到更多关于在调用恢复之前和之后如何使用 ce 的上下文将会有所帮助.

It would help if we could see more context of how ce is used before and after the call to recover.

这篇关于std 函数 std::_Rb_tree_rebalance_for_erase () 中的分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆