在我的设置上运行:
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参考中找到这个,但感觉有点过头了。
答案 0 :(得分:7)
这是未定义的行为,这意味着任何事情都可能发生,包括段错误,或您经历过的事情或其他任何事情。基本上,你很幸运它没有崩溃(或根据观点不幸)。
答案 1 :(得分:3)
我原本以为尝试取消引用超出范围的迭代器会导致段错误。
不,它给出了未定义的行为。该语言不需要检查迭代器访问,因为这需要运行时检查。 C ++通常会尝试避免不必要的运行时开销,让程序员执行任何必要的检查。
大多数现代平台使用分页虚拟内存,提供几千字节的内存保护。这意味着在分配的块(例如由std::vector
管理的块)之后通常存在可访问的内存,在这种情况下,超出范围的访问将简单地踩在该内存上。
可以在C ++库中启用运行时迭代器检查;或者,valgrind或efence等工具可以帮助调试各种内存错误,包括超出范围的访问。
答案 2 :(得分:0)
C ++ Vector实现是使用数组完成的 - 如果大小超过,则会增加底层数组的大小:
以下是Facebook一段时间开源的有趣代码 - 关于内存管理的评论是了解更多内容的好方法Facebook FBvector
你得到的结果相当于访问'C数组'的越界 - 随机: - )