C++映射擦除错误

Error with C++ Maps erase

本文关键字:错误 擦除 映射 C++      更新时间:2023-10-16

我不得不从c++std::map中删除一些条目,为此,我迭代std::map并使用擦除。但我犯了一个错误。错误如下:

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);                 
        }                       
}   

有人能指出错误

您有一个iteratorstd::map,对吗?在for循环中,将iterator初始化到开头。您检查它是否在范围内。然后erase就是iterator。您的iterator现在无效。iterator实际上就像指针,当你erase时,你实际上是在delete指向一个"指向"的值。因此,其他iterator不能保证它们指向有效的东西。

特别是您的erase,导致您的iterator失效。一个有保证的,因为它是iterator,你是erase d。你需要一个新的iterator,最好是在你erase d的后面,对吧?不幸的是,std::map没有提供这种功能。std::map并不是真正打算作为一个顺序容器来处理的。这个想法是通过值的键而不是位置来访问值。当你试图按照它们的顺序擦除时,这是有问题的。

相反,也许你可以根据i来确定你需要擦除哪个密钥?然后使用find查找密钥,使用erase擦除密钥。由于您不再按顺序迭代std::map,因此不再需要担心无效的iterator s。

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

迭代器it由于erase而变得不稳定。