2017-03-05 33 views
2

我编写了下列程序,用于将值推入并将值打印到向量中。看起来,如果我推送以及从矢量打印值,它给了我不确定的行为。例如,我的预期输出应该是:(1,3,4,5),而我的输出是(0,3,4,5)。有人可以解释我的错在哪里。从C++向量推送和检索值的意外输出

#include <iostream> 
#include <vector> 
using namespace std; 

int main() { 
    vector<unsigned> vec; 
    vec.push_back(1); vec.push_back(3); vec.push_back(4); vec.push_back(5); 

    for(vector<unsigned>::iterator i=vec.begin(), l=vec.end(); i!=l; ++i){ 
     vec.push_back(2); 
     cout<<(*i)<<"\n"; 
    } 

    return 0; 
} 
+1

当'push_back()'发生缓冲区扩展时,我听说'std :: vector'的迭代器失效了。 (我想更多的信息应该在回答中) – MikeCAT

回答

6

是的,这是未定义的行为。当在循环内部调用std::vector::push_back时,迭代器i可能失效(如果重新分配发生),那么对它的操作如*i就是UB。而且l肯定会失效。

如果新size()capacity()那么所有迭代器和引用(包括过去的最末端迭代器)是无效的更大。否则只有最后一个迭代器失效。

您可以使用std::vector::reserve来避免重新分配,从而使i失效。例如

vector<unsigned> vec; 
vec.push_back(1); vec.push_back(3); vec.push_back(4); vec.push_back(5); 

vec.reserve(vec.size() * 2); 
for(vector<unsigned>::iterator i = vec.begin(); i != vec.end(); ++i) { 
    cout<<(*i)<<"\n"; 
    vec.push_back(2); 
    ++i; 
    cout<<(*i)<<"\n"; 
} 

注意你应该在迭代的末尾使用vec.end()直接避免l(过去最末端迭代器),和++i无效两次以避免无限循环。

+0

好的......谢谢......但是你是什么意思:否则只有过去最终迭代器失效 –

+0

@JannatArora由于大小改变了'end()'方法必须返回一个新的值,所以旧的无效 –

+0

@JannatArora这意味着如果重新分配没有发生,只有'l'将变为无效,'我'会没事的。 – songyuanyao