Pau*_*zak 22 c++ stl visual-studio
我正在使用Visual Studio 2015 Update 1 C++编译器和此代码段:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v{3, 1, 4};
v.reserve(6);
for (auto e: v)
v.push_back(e*e);
for (auto e: v)
cout << e << " ";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
发布版本运行正常,但调试版本会生成vector iterators incompatible错误消息.这是为什么?
在将基于范围的循环c ++ 11中的元素添加到向量之前将其标记为重复问题之前,请阅读我的答案 /sf/answers/2482748201/,其中包含相反的参数.
Yak*_*ont 16
您的代码显示未定义的行为,但它很棘手,往往只在调试版本中捕获.
执行a时v.push_back,如果size传递容量,则所有迭代器都将失效.你可以通过储备避免这种情况.
但是,即使您没有使容量增长,过去的迭代器仍然会失效.通常,迭代器失效规则不区分"迭代器的'值'将是垃圾/引用不同的对象"和"迭代器的'位置'不再有效".当任何一个发生时,迭代器被认为是无效的.由于结束迭代器不再是结束迭代器(它从引用到任何东西,在几乎每个实现中都引用某些东西),标准只是声明它是无效的.
这段代码:
for (auto e: v)
v.push_back(e*e);
Run Code Online (Sandbox Code Playgroud)
大致扩展到:
{
auto && __range = v;
for (auto __begin = v.begin(),
__end = v.end();
__begin != __end;
++__begin
)
{
auto e = *__begin;
v.push_back(e*e);
}
}
Run Code Online (Sandbox Code Playgroud)
该v.push_back呼叫无效的__end迭代器,然后对进行比较,并调试建立正确的标志未定义行为是一个问题.调试MSVC迭代器非常小心失效规则.
发布版本执行未定义的行为,并且因为向量迭代器基本上是指针周围的薄包装器,并且指向过去结束元素的指针成为在没有容量溢出的推回之后指向最后一个元素的指针,它"作品".
| 归档时间: |
|
| 查看次数: |
743 次 |
| 最近记录: |