我有一个名为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之后。
我显然没有处理角落案件,而且这段代码是错误的。我应该怎么做才能覆盖角落的情况呢?我应该将upper_bound()
替换为find()
还是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)
答案 0 :(得分:2)
比较这两个:
目标是找到大于键的下一个元素,这就是我降低它的原因。原因是地图中有一些重叠的范围。
返回指向容器中第一个元素的迭代器,其中的键被认为是在k之后
这意味着,upper_bound
已经满足您的需求。所以不要减少迭代器。有三个角落案例:
end()
/ begin()
。 UB的递减,增量和解除引用将给予UB。upper_bound
将返回end()
,因此请勿取消引用它。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...
}
}