是一个迭代器vec.end()仍然有效后vec.push_back()时没有重新分配 [英] Is an Iterator to vec.end() still valid after vec.push_back() when there is no reallocation

查看:558
本文介绍了是一个迭代器vec.end()仍然有效后vec.push_back()时没有重新分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此示例代码是否有效?

#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]; // ?
}

VS2010中的错误可能与错误

The error in VS2010 may be related to this bug.

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

If I set the command line option /D_HAS_ITERATOR_DEBUGGING=0 or set

#define _HAS_ITERATOR_DEBUGGING 0
#include<vector>

没有错误。

strong>修改:

根据答案,我认为此代码应该会导致错误。编译器中没有错误。

In light of the answers, I think this code should cause an error. There is no bug in the compiler. It only works in release mode because iterators are implemented as pointers.

推荐答案

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

You are thinking of iterators as pointers.

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

Iterators may use pointers as an implementation detail but they are not actual pointers.

因此:

iter = vec.end() + 1; // This is not valid.

没有两个元素通过数据结尾的事情。

There is no such thing as two elements passed the end of data.

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

vec.end() returns an iterator that when decrement is a reference to the last elements (assuming there are elements). While an iterator referencing the last element when incremented is equivalent to the iterator returned by 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


$ b b

但是解引用由end()表示的迭代器是未定义的behavior()(即使你有保留空间)(实现可能不使用指针)例如一些DeBug STL实现将做广泛的错误检查在迭代器代码中)。

But de-referenceing the iterator representing by end() is undefined behavior() (even if you have reserved space) (the implementation may not be using pointers. For example some of the DeBug STL implementations will do extensive error checking in the iterator code).

这篇关于是一个迭代器vec.end()仍然有效后vec.push_back()时没有重新分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆