std :: advance of std :: multimap end()迭代器由负数崩溃

时间:2014-05-29 02:00:09

标签: c++ crash multimap stdadvance

我的应用程序崩溃了这个操作:

std::multimap<int, std::string, std::greater<int>> mm;
// insert elements
auto it = mm.end();
std::advance(it, -(mm.size() - 7));

以下是崩溃的消息:

Expression: map/set iterator not incrementable

有什么问题?

编辑: 当我只写-1而不是-(mm.size() - 7)它没有崩溃,为什么?调试mm.size()时,请考虑为8。

编辑2: 当我写std::advance(it, -(static_cast<int>(scoresMap.size()) - 7));时,它有效。这是因为多图的大小类型,但仍无法猜出是什么原因。

1 个答案:

答案 0 :(得分:2)

expresion (mm.size() - 7)生成一个无符号值std :: size_t。然后取消无符号值,并根据最近的C ++草案规范(N3690):

  

一元运算符的操作数应具有算术或无范围的枚举类型,结果是其操作数的否定。对整数或枚举操作数执行整体提升。通过从2 n 中减去其值来计算无符号数量的负数,其中n是提升的操作数中的位数。结果的类型是提升的操作数的类型。

由于无符号类型的否定规则,提供给std::advance的值可能会转换为大于mm.size()的某个值。

编辑中的第二个表达式static_cast<int>(scoresMap.size() - 7)将值更改为有符号类型int。但是,如果static_cast返回的值大于scoresMap.size() - 7,则std::numeric_limits<int>::max()会有未定义的行为,否定该值会获得所需的值。