gpt4 book ai didi

c++ - std 函数 std::_Rb_tree_rebalance_for_erase () 中的段错误

转载 作者:行者123 更新时间:2023-11-30 02:11:45 24 4
gpt4 key购买 nike

(请注意任何 future 的读者:毫不奇怪,错误是在我的代码中而不是 std::_Rb_tree_rebalance_for_erase () )

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

准确的错误是

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

在段错误更新两个容器的内容之前成功退出的函数。一个是 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 << 线出现在段错误之前。

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


更新

当我删除 ce.erase( epqItr ); 时,我已经确认段错误消失了(尽管程序随后由于其他原因立即崩溃) .我能够在代码的另一个地方成功地删除事件;我在那里用来删除 ce 中项目的代码与此处的内容相同

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

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 行是空白。

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

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 行。跳转到下方查看令人尴尬的解决方案。

最佳答案

可能您在调用 recover 的过程中将迭代器保存到 ce 中。如果恢复碰巧删除了该项目,迭代器将失效,并且任何 future 的使用(比如尝试删除它)都可能导致段错误。

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

关于c++ - std 函数 std::_Rb_tree_rebalance_for_erase () 中的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2869183/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com