此示例代码有效吗?
#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中的错误可能与此bug有关。
如果我设置命令行选项/D_HAS_ITERATOR_DEBUGGING=0
或设置
#define _HAS_ITERATOR_DEBUGGING 0
#include<vector>
没有错误。
修改
根据答案,我认为此代码应该导致错误。编译器中没有错误。它只能在发布模式下工作,因为迭代器是作为指针实现的。
答案 0 :(得分:7)
23.2.4.3/1:
如果新大小为,则会导致重新分配 大于旧容量。如果不 所有的重新分配都发生了 迭代器和引用之前 插入点仍然有效。如果 抛出异常而不是by 复制构造函数或赋值 T的操作符没有效果。
所以不,end()
在push_back
之后无效。引用与vector.insert
有关,push_back
是根据insert
答案 1 :(得分:6)
您正在考虑将迭代器作为指针。
迭代器可能会使用指针作为实现细节,但它们不是实际的指针。
因此:
iter = vec.end() + 1; // This is not valid.
没有两个元素通过数据末尾。
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
但是,取消引用由end()表示的迭代器是未定义的行为()(即使你有保留空间)(实现可能没有使用指针。例如,一些DeBug STL实现将进行大量的错误检查迭代器代码)。