【问题标题】:Not using iterators into a resized vectors不将迭代器用于调整大小的向量
【发布时间】:2011-01-08 09:12:08
【问题描述】:

我读过《C++ 编程语言:特别版》

Don't use iterators into a resized vector

考虑这个例子。

vector< int >::iterator it = foo.begin();

while ( it != foo.end() ) {
  if ( // something ) {
    foo.push_back( // some num );
  }
  ++it;
}

这有问题吗?向量调整大小后,循环条件中的 foo.end() 会不会前推1?

附:此外,如果向量为 x 个整数保留空间怎么办。如果 push_back 没有违反这个空间,它仍然是一个问题(我会假设如果 it.end() 指向一个过去包含某些东西的向量中的最后一个元素)。

【问题讨论】:

    标签: c++ iterator containers


    【解决方案1】:

    是的,有问题。

    push_back 的任何调用都有可能使向量中的所有 迭代器无效。

    foo.end() 将始终检索有效的结束迭代器(可能与foo.end() 最后返回的值不同),但it 可能已失效。这意味着增加或比较它可能会导致未定义的行为。

    【讨论】:

    • 如果向量的大小适合 10 个整数。假设 push_back 没有超过这个预先分配的大小,它仍然会使迭代器失效吗?
    • @Person: 严格来说,如果push_back 不会导致向量的size() 超过先前在对reserve 的调用中给出的请求容量,那么您可以保证对@987654328 的调用@ 不会导致重新分配,也不会使对象的迭代器无效。不过,您仍然需要致电 end() 才能获得正确的 end()
    • 谢谢。我认为最好不要保留空间和使用迭代器,而在这种情况下只使用数组索引。
    【解决方案2】:

    是的,有问题。不管foo.end()it 都可能被push_back() 失效。编辑:(即不是 just 结束可能会改变;可能会重新分配向量的 whole 缓冲区,因此 all 迭代器无效)。

    【讨论】:

      【解决方案3】:

      是的,这有问题。 push_back 使您调用它的向量的任何迭代器无效。所以调用push_back之后,再执行++it也是不合法的。这是一种未定义行为的情况,因此它有时可能会起作用,有时可能会失败,但您永远不应该依赖它起作用。

      【讨论】:

        【解决方案4】:

        正如其他人所说,push_back() 可能会使向量的所有迭代器无效。原因是向量中的数据存储在连续内存的区域中。如果 push_back() 或任何其他调整向量大小的操作导致向量的大小超过分配区域的容量,则该区域将被重新分配并最终在内存中的不同位置,而所有迭代器仍将是引用旧的内存区域。

        【讨论】:

          猜你喜欢
          • 2010-12-10
          • 2016-10-14
          • 2014-03-23
          • 1970-01-01
          • 1970-01-01
          • 2021-04-09
          • 1970-01-01
          • 1970-01-01
          • 2018-05-02
          相关资源
          最近更新 更多