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

std::queue::size() can return a huge number after pop() of size() == 0

本文关键字:size 返回 一个 数字 巨大 之后 pop std queue      更新时间:2023-10-16

我这里有链接,我push(x) 10 int秒,然后pop() 11,大小不是 0,或者是一个例外,而是一个震撼的数字(可能是== std::numeric_limit<size_type>::max())。我认为这是内部表示只是做一个size--而不是检查已经empty()案例的结果。这似乎是 stdc++ 库中的一个错误。

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

被称为"未定义的行为"。为了节省实现时间(不检查它是否已经为空),尽管"没有什么可减少的",但实现只会减少。不要这样做(在另一个实现上它可能不会这样做,所以绝对不要依赖它做任何有意义的事情)。由于它未定义,它还可能在调制解调器上拨出到澳大利亚,擦除硬盘或导致应用程序崩溃。或者别的什么...

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

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

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

并使用safe_pop(que);而不是que.pop();

即使

队列为空,队列大小数据成员也可能在pop()中递减。大小数据成员很可能具有无符号整数类型,当您递减无符号零时,它只是换行到最大的可表示值。

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

当你弹出 1 多于推送时,内部你会得到大小 -1。但是size_t是无符号的,因此 -1 被类型转换为(无符号最大长度 - 1)。但是,无意"修复"此问题,因为它将添加额外的检查代码并可能导致性能问题。与托管语言不同,C++开发人员不希望有任何可能导致性能下降的额外内容:)。

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