2

次のC++コードは

int main()
{
    vector <int> myvect(3,0);
    vector <int> :: iterator it;
    it = myvect.begin();
    myvect.insert(it,200);
    myvect.insert(it+5,400);         //Not sure what 5 makes the difference here
    cout << myvect[0] << endl << myvect[1];
}

出力:

200
400

そして、マイナーな変更を加えた同じコードは

int main()
{
    vector <int> myvect(3,0);
    vector <int> :: iterator it;
    it = myvect.begin();
    myvect.insert(it,200);
    myvect.insert(it+4,400);         //Not sure what 4 makes the difference here
    cout << myvect[0] << endl << myvect[1];
}

出力:

400
200

イテレータに4または5を追加すると、要素の順序が変わる理由を誰かに教えてもらえますか?

ありがとう

4

2 に答える 2

7

プログラムの動作は未定義です。

v.begin() + 53つの要素(すべて0に初期化されている)のベクトルを作成し、ベクトルの終わりを超えた位置に要素を挿入しています。

さらに、イテレータを使用しています(位置が指すit)に要素を挿入した後。C++11標準の23.3.6.5/1項によると:it

[...]再割り当てが発生しない場合、挿入ポイントの前のすべてのイテレータと参照は有効なままです。[...]

したがって、イテレータit自体はステートメントの後で有効であることが保証されておらずmyvect.insert(it, 200)、次の命令(myvect.insert(it + 4, 400))でそれを使用することは未定義動作です。

未定義動作のプログラムは期待できません。クラッシュしたり、奇妙な結果が得られたり、(最悪の場合)期待どおりに動作したりする可能性があります。

于 2013-02-25T00:26:02.480 に答える
1

メンバー関数vector::insert(const_iterator, const value_type&)には、ベクトルを参照する有効なイテレーターが必要ですが、有効なイテレーターではit+4ありit+5ません。

最初の挿入の前it+3は、有効な(参照解除できない)イテレータであり、ベクトルシーケンスの終わりを過ぎたところを指しますが、it+4無効です。挿入it 無効になる可能性があります。その場合、を使用する式itは有効ではありませんit+5。シーケンスにその時点で4つの要素しかないためではありません。

次のように変更すると、コードは有効になります。

it = myvect.begin();
myvect.insert(it,200);
it = myvect.begin();     // make it valid again
myvect.insert(it+4,400);
于 2013-02-25T00:31:18.267 に答える