3

我有一个 C++ 应用程序,它有一次无法重现的断言失败。这是一次失败的代码:

unsigned int test(std::vector<CAction> actionQueue) {
  unsigned int theLastCount = actionQueue.size() - 1;

  std::vector<CAction>::const_reverse_iterator rItr = actionQueue.rbegin();
  std::vector<CAction>::const_reverse_iterator rEndItr = actionQueue.rend();

  for (; rItr != rEndItr; ++rItr, --theLastCount) {
    const CAction &fileAction = *rItr;

    if (fileAction.test()) {
      continue;
    }
    return theLastCount;
  }

  assert(theLastCount == 0); // How could this fail?

  return theLastCount;
}

不知何故,循环完成后 theLastCount 不为零。

从我对逻辑的阅读来看,这应该是不可能的,除非:

  1. 其他一些线程影响了actionQueue(我认为这是不可能的)。
  2. 发生了一些短暂的内存损坏。

我在这里错过了什么愚蠢的东西,我的代码中是否有错误?请注意,在我看到这一点的情况下, theLastCount 应该已初始化为 1,因为该向量有两个元素。

4

5 回答 5

5

我相信如果所有文件操作都通过了 test(),则 theLastCount 将为-1。考虑:

theLastCount 从 actionQueue.size() -1 开始。对于 actionQueue 中的每个项目,您将其递减一次 - 也就是说,它现在是 actionQueue.size() - 1 - actionQueue.size() = -1。想想看。theLastCount 保存当前迭代器的索引。但是当当前迭代器是rend时,那是数组开头之前的一个迭代器-即-1。

编辑:哦,它没有签名。但是由于您只测试是否等于零,因此积分溢出在这里并不重要。

于 2011-01-15T19:57:46.707 回答
2

如果您的 actionQueue 为空,则

unsigned int theLastCount = actionQueue.size() - 1;

将设置theLastCount为最大可能的无符号整数。内部循环将永远不会执行,因为反向迭代器彼此相等(rbegin() == rend()在空容器上),因此您将遇到theLastCount等于某个惊人数字的断言。

于 2011-01-15T19:57:20.343 回答
1
void test(std::vector<CAction> actionQueue) 
{
  unsigned int theLastCount = actionQueue.size() - 1;
  /** Omitted code ***/
  {
    /** Omitted code ***/
    return theLastCount;
  }
  return theLastCount;
}

忘记您无法重现的错误。但这是一个严重的问题。返回类型是void,但你返回unsigned int!怎么来的?


我想,你需要这样写:

assert(theLastCount == -1);//correct assert!

那是因为如果test()所有元素都通过,那么 theLastCount 应该变成 -1。由于没有剩余元素,如果有元素,theLastCount 始终是有效的元素索引。否则它应该变成-1。

注意:将类型theLastCount从更改unsigned intint

于 2011-01-15T20:01:10.423 回答
1

在将代码发布到此处之前,请编译并运行您的代码!首先,这段代码不能编译(我不会告诉你为什么——你可以问你的编译器)。其次,您的断言永远不会成功,因为 theLastCount 将始终为 (unsigned int)-1。

于 2011-01-15T20:05:53.993 回答
0

如果队列为空怎么办?

theLastCount将是-1,然后... :-)

于 2011-01-15T19:58:13.173 回答