【问题标题】:Error with C++ Maps eraseC++ Maps 擦除错误
【发布时间】:2012-02-17 10:16:41
【问题描述】:

我不得不从 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);                 
        }                       
}   

谁能指出错误

【问题讨论】:

  • 这是使用set 的一种不同寻常的方式。也许你应该仔细检查它是否真的是正确的容器类型。
  • @KerrekSB: set?你在哪里看到set?起得太晚了吧?
  • @Als:哦,对不起。地图,布景,同样的东西……太醉了,不能清楚地张贴,我最好闭嘴!

标签: c++ map


【解决方案1】:
int n = nlsize - MAXNL;
while (n-- > 0) {
    LettersMap.erase(LettersMap.begin());
}

迭代器iterase 而变得不稳定。

【讨论】:

  • 你的意思可能是无效
  • 是的 invalidated 是 C++ STL 参考中使用的术语。我发现这对于指向错误的事情来说太无害了。
【解决方案2】:

你有一个iteratorstd::map,对吧?在for 循环中,将iterator 初始化为开头。你检查它是否在界限内。然后你eraseiterator。您的 iterator 现在无效。 iterators 实际上就像指针,当您 erase 时,您实际上是在 deleteing 一个“指向”的值。因此,其他iterators 不能保证他们指向的东西是有效的。

具体来说,您erase,导致您的iterator 失效。有保证的,因为它是iteratorerased。你需要一个新的iterator,最好是在你erased 之后的位置,对吧?不幸的是,std::map 不提供该功能。 std::map 并不是真正打算被视为顺序容器。这个想法是您通过它们的键而不是它们的位置来访问值。看到你试图按顺序擦除,这是有问题的。

相反,也许您可​​以根据i 确定需要擦除的密钥?然后使用find 找到密钥并使用erase 擦除密钥。由于您不再按顺序遍历您的 std::map,因此您不再需要担心 iterators 无效。

【讨论】:

  • 这个,或者,你知道的,使用合适的容器来存储你要存储的任何东西。听起来std::map 可能不是适合这项工作的工具。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-22
相关资源
最近更新 更多