2017-03-05 8 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にならないようにすることができます。例えばあなたは無限ループを避けるために、イテレーションの終わりに二回l(過去エンドイテレータ)、および++iの無効化を避けるために、直接vec.end()を使用する必要があります

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"; 
} 

注意。

+0

Ok ...ありがとう...しかし、どういう意味ですか?そうでなければ、過去のイテレータだけが無効にされます。 –

+0

@JannatAroraサイズが変更されるので、 'end()'メソッドは新しい値を返さなければならないので、古いものは無効です –

+0

@JannatArora再割り当てが起こらない場合、 'l'だけが無効になり、' i'はうまくいくでしょう。 – songyuanyao

関連する問題