将元素推送到基于范围的 for 循环中的向量
Pushing elements to a vector within a ranged based for loop
有人可以向我解释为什么这个简单的代码:
#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
后添加v.reserve(12)
可以解决问题。在push_back
操作期间,肯定有一些与矢量重新分配以扩大其容量有关的东西。
但我想知道这是否只是一个不确定的行为,我很幸运只有第二个元素是错误的,或者这是否是可预测和可解释的(考虑到for
循环的工作原理)。
基于范围 for 循环的形式为
{
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
将导致未定义的行为,因为您使用的是不再有效的迭代器。
在第一个push_back
之后,向量重新分配其缓冲区,并且范围 for 循环中的迭代器将失效。
这是因为 for 循环使用的迭代器在回推期间可能会失效。在后台,向量使用缓冲区,push_back可能导致数组被重新分配。
更多参考资料在这里:http://www.cplusplus.com/forum/general/5189/
vector::p ush_back memory的引擎盖下会发生什么?
相关文章:
- 在基于范围的for循环中使用结构化绑定声明
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- 基于范围的 for 循环unordered_map和引用
- C++基于范围的 for 循环和元素副本
- 实现基于链表的堆栈的基于范围的 for 循环
- 在基于范围的 for 循环期间插入 std::list 的后面
- 基于范围的 for 循环range_declaration中各种说明符之间的性能差异
- 避免在基于反向范围的for循环实现中悬挂参考
- C++ - 使用基于范围的 for 循环将字符值分配给向量中的字符串不会分配值
- 转到基于范围的 for 循环中的下一个迭代器
- 使用基于数组和范围的 For 循环替换一些基本代码行
- C++:返回一个基于范围 for 循环迭代器,其中包含继承对象
- 布尔值向量的基于范围 for 循环
- 在 c++ 中基于范围的 for 循环中使用引用作为控制变量
- C++11 基于范围的 for 循环,用于 std::list
- 堆分配数组的基于范围的 for 循环
- 关于在向量向量上使用基于范围的 for 循环
- 如何使用基于范围的for循环迭代Rapidjson文档(它本身就是一个JSON数组)
- 使用基于范围的for循环取消对矢量指针的引用