2012-01-24 10 views
1

我不得不從C++ std::map刪除一些條目,爲此我遍歷std::map和使用的擦除。但是我得到一個錯誤。該錯誤是這樣的:錯誤使用C++地圖抹去

0x0017f3f6 in std::_Rb_tree_rebalance_for_erase() from /usr/local/lib/libstdc++.so.6 
(gdb) bt 
#0 0x0017f3f6 in std::_Rb_tree_rebalance_for_erase() from /usr/local/lib/libstdc++.so.6 
#1 0x00487ef4 in getLetters() from /usr/lib/libmail.so 
#2 0x0048cacc in getHeader() from /usr/lib/libmail.so 

#6 0x08048802 in __gxx_personality_v0() 
#7 0x00251e9c in __libc_start_main() from /lib/libc.so.6 
#8 0x080486a1 in __gxx_personality_v0() 
(gdb) 

的代碼是這樣的:

int nlsize=LettersMap.size(); 

if(nlsize > MAXNL)    
{        
     std::map <std::string,MSG_HEADER>::iterator it; 
     int i=0;     
     for(i=0, it=LettersMap.begin(); i <nlsize-MAXNL ;i++, it++) 
     {      
       LettersMap.erase(it);     
     }      
} 

是否有人可以指出錯誤

+0

[調用erase()後std :: map :: iterator的問題可能重複)(http://stackoverflow.com/questions/4636182/problem-with-stdmapiterator-after-calling-erase) – rerun

+0

這是一個有點不尋常的方式來使用'set'。也許你應該仔細檢查它是否真的是正確的容器類型。 –

+1

@KerrekSB:'set'?你在哪裏看到一個'set'?太晚了,是嗎? –

回答

2
int n = nlsize - MAXNL; 
while (n-- > 0) { 
    LettersMap.erase(LettersMap.begin()); 
} 

迭代器it變得不穩定的erase

+2

你可能意思是*失效*。 –

+0

是_invalidated_是C++ STL參考中使用的術語。我發現這些東西指向錯誤是無害的。 –

3

你有一個iteratorstd::map,對不對?在您的for循環中,您將iterator初始化爲開頭。你檢查它是否在界限內。然後你eraseiterator。您的iterator現在無效。 iterator s實際上就像是指針,當你erase時,你實際上是一個「指向」的值。因此,其他iterator不能保證他們指向某些有效的東西。

具體來說,您erase,使您的iterator的無效。有保證的,因爲它是iteratorerase d。你需要一個新的iterator,最好是在你之後erased之後,對吧?不幸的是,std::map不提供該功能。 std::map並非真正意圖被視爲順序容器。這個想法是你通過他們的鑰匙來訪問價值,而不是他們的位置。看到你試圖通過順序排序擦除,這是有問題的。

相反,也許,你能確定你需要清除基於i哪個鍵?然後使用find查找密鑰並使用erase擦除密鑰。由於您不再依次迭代您的std::map,因此您不必再擔心iterator無效。

+0

這或者,你知道,使用適當的容器,無論你正在存儲什麼。這聽起來像'std :: map'可能不適合這項工作。 –