繁体   English   中英

如何正确处理upper_bound的迭代器

[英]How to correctly handle an iterator for upper_bound

我有一个名为tableMap的C ++映射,它是一个std::map<int, std::string>

void processMap(int key) {
  std::map<int, std::string>::const_iterator iter;
  while (true) {
     // key is an argument to the function
     iter = tableMap.upper_bound(key);
     --iter;
     std::string value = iter->second;
     // do something else  
     ...
  }
}

关键是我没有正确处理upper_bound函数调用。 此外,我不能只检查

if (iter != tableMap.end())

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

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

我显然没有处理角落的情况,那段代码是错误的。 我应该怎么做才能覆盖角落的情况呢? 我应该用find()还是lower_bound()替换upper_bound() lower_bound()

我们的目标是要找到下一个元素大于key ,所以这就是为什么我降低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之后

这意味着, upper_bound已经满足您的需求。 所以不要减少迭代器。 有三个角落案例:

  1. 映射为空,然后只有一个迭代器,即end() / begin() UB的递减,增量和解除引用将给予UB。
  2. 地图不包含任何值,其键大于您的参数。 upper_bound将返回end() ,因此不要取消引用它。
  3. 地图仅包含键大于您的参数的值。 upper_bound将返回begin() 你的减量是UB然后,但是因为它是错的,你可以使用它并取消引用它。

所以你只需要处理前两种情况,其中upper_bound返回end()

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...
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM