2

在我的设置上运行它:

  vector<int> myvector;
  for (int i=1; i<=5; i++) myvector.insert(myvector.end(),i);

  vector<int>::iterator it;
  for ( it=myvector.begin() ; it < myvector.end()+2; it++ )
    cout << " " << *it;

产量:

1 2 3 4 5 0 0

我原以为尝试取消引用超出范围的迭代器会导致段错误。但它似乎产生了向量中包含的类型的空对象或默认初始化对象。

这是明确定义的行为吗?这个属性是从哪里来的,来自迭代器还是来自向量?迭代器是否在某种意义上捕获了超出范围的异常并返回一个空对象?

我尝试在 C++11 参考中找到它,但感觉有点过头了。

4

3 回答 3

6

这是未定义的行为,这意味着任何事情都可能发生,包括段错误、您所经历的事情或其他任何事情。基本上,你很幸运它没有崩溃(或者不走运,基于观点)。

于 2012-11-23T10:34:21.367 回答
3

我原以为尝试取消引用超出范围的迭代器会导致段错误。

不,它给出了未定义的行为。该语言不需要检查迭代器访问,因为这需要运行时检查。C++ 通常会尽量避免不必要的运行时开销,让程序员执行任何必要的检查。

大多数现代平台使用分页虚拟内存,以几千字节的粒度提供内存保护。这意味着在分配的块(例如由 管理的块std::vector)之后通常有可访问的内存,在这种情况下,超出范围的访问只会踩到该内存。

可以在 C++ 库中启用运行时迭代器检查;或者,诸如valgrindefence 之类的工具可以帮助调试各种内存错误,包括超出范围的访问。

于 2012-11-23T10:50:22.660 回答
0

C++ Vector 实现是使用数组完成的——如果大小超过,那么它会增加底层数组的大小:
这是 Facebook 不久前开源的一些有趣的代码——关于内存管理的评论是了解更多内容的好方法在引擎盖下Facebook FBvector

你得到的结果相当于“C 数组”的越界访问 - 随机 :-)

于 2012-11-23T10:46:38.727 回答