[英]Infrequent segmentation fault in accessing boost::unordered_multimap or struct
我在調試細分錯誤時遇到問題。 我希望您能找到有關縮小問題范圍的技巧。
當迭代器嘗試訪問結構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”。 recoveryTime很好,並且代碼中的assert(...)
也未觸發。
正如我所說,在數千次成功的恢復事件之后,此段錯誤似乎“隨機地”出現。
您將如何了解正在發生的事情? 我很想知道可能出什么問題以及如何進一步調查問題。
更新資料
我在for循環中添加了一個新的assert和一個檢查:
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 );
}
}
現在,在成千上萬次成功恢復之后,再次在(*it).first
調用中出現EXC_BAD_ACCESS錯誤。 誰能給我提示如何解決此問題的發生? 我正在嘗試使用gdb。 回溯中的幀0讀取
“ Host.cpp:317上的Host :: recover中的#0 0x0000000100001d50(此= 0x100530d80,s = 0,recoverTime = 635.91148029170529)”
我不確定在這里可以提取哪些有用的信息。
更新2
我加了點break;
在carriage.erase(it)
。 這可行。
如果我錯了,請糾正我,但我敢打賭,擦除無序多映射中的項目會使指向它的所有迭代器無效。 嘗試“它=馬車.erase(它)”。 您還必須對ret做一些事情。
更新以回復您的最新更新:
調用“ carriage.erase(it)”后退出循環的原因修復了該錯誤,是因為您停止嘗試訪問已擦除的迭代器。
使用gcc -g
編譯程序並在gdb
下運行它。 發生EXC_BAD_ACCESS
崩潰時,您將進入gdb命令行。 那時,您可以鍵入bt
以獲得回溯,這將向您顯示如何到達崩潰發生的位置。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.