当没有重新分配时,vec.nd()的迭代器在vec.push_back()之后仍然有效

Joh*_*nPS 1 c++ iterator

这个示例代码有效吗?

#include<vector>
using namespace std;

int main() {
  vector<int> vec(10); // create with 10 elements
  vec.reserve(100);    // set capacity to 100
  vector<int>::iterator iter = vec.end(); // points 1 past vec[9]

  vec.push_back( 777 );

  bool is_this_valid_and_true =  *iter == vec[10]; // ?

  // VS2010 runtime error in debug build:
  // Expression: vector iterator not dereferencable
  // Works in release build

  iter = vec.end() + 1; // points 2 past vec[10]?
  vec.push_back( 888 );
  vec.push_back( 999 );

  is_this_valid_and_true =  *iter == vec[12]; // ?
}
Run Code Online (Sandbox Code Playgroud)

VS2010中的错误可能与此错误有关.

如果我设置命令行选项/D_HAS_ITERATOR_DEBUGGING=0或设置

#define _HAS_ITERATOR_DEBUGGING 0
#include<vector>
Run Code Online (Sandbox Code Playgroud)

没有错误.

编辑:

根据答案,我认为此代码应该导致错误.编译器中没有错误.它只能在发布模式下工作,因为迭代器是作为指针实现的.

Eri*_*rik 7

23.2.4.3/1:

如果新大小大于旧容量,则会导致重新分配.如果没有重新分配, 插入点之前的所有迭代器和引用仍然有效.如果除了T的复制构造函数或赋值运算符之外抛出异常,则没有任何影响.

所以不,之后end()不必有效push_back.引用与...相关vector.insert,push_back是根据insert


Mar*_*ork 6

您正在考虑将迭代器作为指针.

迭代器可以使用指针作为实现细节,但它们不是实际的指针.

从而:

iter = vec.end() + 1; // This is not valid.
Run Code Online (Sandbox Code Playgroud)

没有两个元素通过数据末尾的事情.

vec.end()返回一个迭代器,当递减是对最后一个元素的引用时(假设有元素).虽然在递增时引用最后一个元素的迭代器等效于end()返回的迭代器.

// Note: Assuming vector iterators were not invalidated after an insert anyway.
//       But for arguments sake lets play this out.
//
vector<int>::iterator iter = vec.end(); // points 1 past vec[9]
vec.push_back( 777 );
bool is_this_valid_and_true =  *iter == vec[10]; // Not valid.
                                                 // This is the end() iterator
                                                 // de-referencing it is UB
Run Code Online (Sandbox Code Playgroud)

但是取消引用由end()表示的迭代器是未定义的行为()(即使你有保留空间)(实现可能没有使用指针.例如,一些DeBug STL实现将在迭代器代码中进行大量的错误检查).