如何正确处理上界迭代器 我有一个C++映射,叫做TabLAMAP,它是一个 STD::MAP< /Cord>

如何正确处理上界迭代器 我有一个C++映射,叫做TabLAMAP,它是一个 STD::MAP< /Cord>,c++,map,iterator,C++,Map,Iterator,因为如果键位于最后一个元素上,那么上限将返回end()。从C++API,我们有: 将迭代器返回到上限 返回一个迭代器,该迭代器指向容器中的第一个元素,该元素的键被认为在k之后。 很明显,我没有处理角落里的案子,那段代码有缺陷。在其他情况下,我应该做些什么来覆盖角落案例?我应该用find()或lower\u-bound()替换上限() 目标是找到下一个大于键的元素,这就是我减少iter的原因。原因是地图上有些重叠的区域 Program received signal SIGSEGV, Segmen

因为如果键位于最后一个元素上,那么
上限
将返回
end()
。从
C++
API,我们有:

将迭代器返回到上限 返回一个迭代器,该迭代器指向容器中的第一个元素,该元素的键被认为在k之后。

很明显,我没有处理角落里的案子,那段代码有缺陷。在其他情况下,我应该做些什么来覆盖角落案例?我应该用
find()
lower\u-bound()替换
上限()

目标是找到下一个大于
的元素,这就是我减少
iter
的原因。原因是地图上有些重叠的区域

Program received signal SIGSEGV, Segmentation fault.
0x0000003d3ba69eea in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.47.el6_2.5.x86_64 keyutils-libs-1.4-4.el6.x86_64 krb5-libs-1.8.2-3.el6_0.3.x86_64 libcom_err-1.41.12-3.el6.x86_64 libgcc-4.4.6-3.el6.x86_64 libibverbs-1.1.5mlnx1-1.32.gc42bcbf.x86_64 libselinux-2.0.94-2.el6.x86_64 libstdc++-4.4.6-3.el6.x86_64 openssl-1.0.0-4.el6_0.2.x86_64 pcre-7.8-3.1.el6.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x0000003d3ba69eea in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
#1  0x0000000000da8a41 in std::_Rb_tree_const_iterator<int, std::string >::operator-- (this=0x7fffffffb8b0)
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:274
#2  0x0000000000de18db in processMap (
    this=0x17107b8,key=0)
程序接收信号SIGSEGV,分段故障。
0x0000003d3ba69eea在std:_Rb_tree_decreation(std:_Rb_tree_node_base*)中,从/usr/lib64/libstdc++.so.6
缺少单独的调试信息,英语学习英语学习英语学习图书馆图书馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆馆SSL-1.0.0-4.el6_0.2.x86_64 pcre-7.8-3.1.el6.x86_64zlib-1.2.3-27.el6.x86_64
(gdb)英国电信
#0 0x0000003d3ba69eea在/usr/lib64/libstdc++.so.6的std:_Rb_tree_减量(std:_Rb_tree_node_base*)中
#std:_Rb_tree_const_iterator::operator--(this=0x7fffffffb8b0)中的1 0x0000000000da8a41
在/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../../../../../include/c++/4.4.6/bits/stl_tree.h:274
#processMap中的2 0x0000000000de18db(
此参数=0x17107b8,键=0)
比较这两个:

我们的目标是找到下一个大于键的元素,这就是我降低iter的原因。原因是地图上有些重叠的区域

Program received signal SIGSEGV, Segmentation fault.
0x0000003d3ba69eea in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.47.el6_2.5.x86_64 keyutils-libs-1.4-4.el6.x86_64 krb5-libs-1.8.2-3.el6_0.3.x86_64 libcom_err-1.41.12-3.el6.x86_64 libgcc-4.4.6-3.el6.x86_64 libibverbs-1.1.5mlnx1-1.32.gc42bcbf.x86_64 libselinux-2.0.94-2.el6.x86_64 libstdc++-4.4.6-3.el6.x86_64 openssl-1.0.0-4.el6_0.2.x86_64 pcre-7.8-3.1.el6.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) bt
#0  0x0000003d3ba69eea in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
#1  0x0000000000da8a41 in std::_Rb_tree_const_iterator<int, std::string >::operator-- (this=0x7fffffffb8b0)
    at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:274
#2  0x0000000000de18db in processMap (
    this=0x17107b8,key=0)
返回一个迭代器,该迭代器指向容器中的第一个元素,该元素的键被认为在k之后

这意味着,
上限
已经满足了您的需要。所以不要减少迭代器。有三种情况:

  • 映射为空,则只有一个迭代器,即
    end()
    /
    begin()
    。iter的减量、增量和解引用将给出UB
  • 映射不包含键大于参数的值
    上限
    将返回
    end()
    ,因此不要取消引用它
  • 映射仅包含键大于参数的值<代码>上限
  • 将返回
    begin()
    。你的减量是UB,但是因为它无论如何都是错误的,你可以使用它并取消引用它 因此,您只需处理前两种情况,
    上限
    返回
    end()

    比较这两个:

    我们的目标是找到下一个大于键的元素,这就是我降低iter的原因。原因是地图上有些重叠的区域

    Program received signal SIGSEGV, Segmentation fault.
    0x0000003d3ba69eea in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
    Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.47.el6_2.5.x86_64 keyutils-libs-1.4-4.el6.x86_64 krb5-libs-1.8.2-3.el6_0.3.x86_64 libcom_err-1.41.12-3.el6.x86_64 libgcc-4.4.6-3.el6.x86_64 libibverbs-1.1.5mlnx1-1.32.gc42bcbf.x86_64 libselinux-2.0.94-2.el6.x86_64 libstdc++-4.4.6-3.el6.x86_64 openssl-1.0.0-4.el6_0.2.x86_64 pcre-7.8-3.1.el6.x86_64 zlib-1.2.3-27.el6.x86_64
    (gdb) bt
    #0  0x0000003d3ba69eea in std::_Rb_tree_decrement(std::_Rb_tree_node_base*) () from /usr/lib64/libstdc++.so.6
    #1  0x0000000000da8a41 in std::_Rb_tree_const_iterator<int, std::string >::operator-- (this=0x7fffffffb8b0)
        at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:274
    #2  0x0000000000de18db in processMap (
        this=0x17107b8,key=0)
    
    返回一个迭代器,该迭代器指向容器中的第一个元素,该元素的键被认为在k之后

    这意味着,
    上限
    已经满足了您的需要。所以不要减少迭代器。有三种情况:

  • 映射为空,则只有一个迭代器,即
    end()
    /
    begin()
    。iter的减量、增量和解引用将给出UB
  • 映射不包含键大于参数的值
    上限
    将返回
    end()
    ,因此不要取消引用它
  • 映射仅包含键大于参数的值<代码>上限将返回
    begin()
    。你的减量是UB,但是因为它无论如何都是错误的,你可以使用它并取消引用它
  • 因此,您只需处理前两种情况,
    上限
    返回
    end()


    此外,如果
    上限()
    返回
    开始()
    ,则以下
    --iter
    无效。感谢您的编辑。如果目标是在
    之后找到下一个元素,则无需减少迭代器。如果是
    end()
    ,这意味着没有大于
    key
    的元素。只要检查
    if(iter!=tableMap.end())
    就足够了。请注意,对于
    map
    ,使用
    上限没有多大意义。使用
    上限
    的通常原因是查找具有指定键的最后一项,但
    映射
    仅允许一项具有任何给定键<代码>下限
    上限
    相等范围
    主要用于允许多个等效密钥的容器(例如,
    multimap
    )。@JerryCoffin这是不正确的
    上限
    给出大于参数的第一个元素。考虑一个<代码>集合{2,4/8} 和<代码>上限(5)< /代码>,您将得到迭代器指向8。代码>查找(5)将返回
    end()
    。(当然,地图也是如此)。只有
    上限
    下限
    的组合才能在唯一的密钥容器中找到
    。此外,如果
    上限()
    返回
    开始()
    ,则以下
    --iter
    无效。感谢您的编辑。如果目标是在
    之后找到下一个元素,则无需减少迭代器。如果是
    end()
    ,这意味着没有大于
    key
    的元素。只要检查
    if(iter!=tableMap.end())
    就足够了。请注意,对于
    map
    ,使用
    上限没有多大意义。使用
    上限
    的通常原因是查找具有指定键的最后一项,但
    映射
    仅允许打开
    void processMap(int key) {
      while (true) {
         auto iter = tableMap.upper_bound(key);
         if (iter == tableMap.end())
           break; //there is no entry with a greater key
    
         // use iter...
      }
    }