std :: queue :: size()可以在size()== 0的pop()之后返回一个巨大的数字

时间:2015-01-30 22:26:05

标签: c++ c++11 libstdc++

我的链接位于push(x) 10 int s,然后是pop() 11且大小不是0,或者是异常,但是是一个重要的数字(可能是{{1} }})。我认为这是内部表示只是执行== std::numeric_limit<size_type>::max()而不检查已经size--情况的结果。这似乎是stdc ++库中的一个错误。

http://coliru.stacked-crooked.com/a/27ae7f10855e6c23

4 个答案:

答案 0 :(得分:8)

它被称为&#34;未定义的行为&#34;。为了节省实现的时间(不检查它是否已经为空),尽管存在“没有减少任何东西”的情况,实施将简单地减少。不要这样做(而在另一个实现上它可能不会这样做,所以绝对不要依赖它做任何有意义的事情)。由于它未定义,它也可能在您的调制解调器上拨打到澳大利亚,擦除您的硬盘或导致应用程序崩溃。或其他什么......

答案 1 :(得分:3)

popqueue不正确。这样做意味着标准没有定义发生的事情,并且大多数实现(在发布/优化版本中)只是做坏事并且不检查。

如果您需要安全弹出,请尝试:

template<class Q>
void safe_pop(Q&q){
  if (!q.empty())
    q.pop();
}

并使用safe_pop(que);代替que.pop();

答案 2 :(得分:1)

即使队列为空,队列大小数据成员也可能在pop()中递减。大多数情况下,size数据成员都有一个无符号整数类型,当你递减一个无符号的零时,它只是回绕到最大的可表示值。

编辑:已确认,18446744073709551615是0xFFFFFFFFFFFFFFFF十六进制,这是可以用8个字节表示的最大值。

答案 3 :(得分:0)

当您弹出1次以上时,在内部获得大小-1。但是size_t是无符号的,因此-1被转换为(unsigned max long - 1)。但是,无意“修复”此问题,因为它会在代码中添加额外的检查,并可能导致性能问题。与托管语言不同,C ++开发人员不需要任何可能导致性能轻微下降的额外内容:)。

这是GCC的相关主题: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55841