有人可以向我解释为什么这个简单的代码:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {0, 1, 2, 3, 4, 5};
for(auto i: v)
{
std::cout << i << ' ';
}
std::cout << std::endl;
for(auto i: v)
{
std::cout << i << ' ';
v.push_back(4);
}
std::cout << std::endl;
for(auto i: v)
{
std::cout << i << ' ';
}
}
此处发布的代码:http://cpp.sh/5kxdu
输出:
0 1 2 3 4 5
0 0 2 3 4 5
0 1 2 3 4 5 4 4 4 4 4 4
虽然我期待:
0 1 2 3 4 5
0 1 2 3 4 5
0 1 2 3 4 5 4 4 4 4 4 4
我知道在for
循环期间修改向量是不好的(当我点击它时只是尝试别的东西)。在v
声明后,v.capacity()
会返回6
,很明显,在声明v.reserve(12)
后添加v
会解决问题。肯定有一些与向量重新分配有关的东西,以便在push_back
操作期间扩展其容量。
但是我想知道这是否只是一个未确定的行为而且我很幸运,只有第二个元素是错误的,或者这是可预测和可解释的(考虑for
循环如何工作)。
答案 0 :(得分:7)
{
auto && __range = range_expression ;
for (auto __begin = begin_expr,
__end = end_expr;
__begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
并在循环开始时设置begin
和end
迭代器。当您调用push_back
时,它总是使end
迭代器无效,如果size
增长大于capacity
,则所有迭代器都将失效。
因此,当您使用不再有效的迭代器时,使用push_back
会导致未定义的行为。
答案 1 :(得分:2)
在第一个push_back
之后,向量重新分配其缓冲区,并且在ranged for循环中的迭代器无效。
答案 2 :(得分:1)
这是因为for循环使用的迭代器在回退期间可能无效。在引擎盖下,向量使用缓冲区,而push_back可以使数组重新分配。
此处有更多参考资料: http://www.cplusplus.com/forum/general/5189/
What happens under the hood of vector::push_back memory wise?