簡體   English   中英

訪問boost :: unordered_multimap或struct的不頻繁分段錯誤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM