my_question
my_question

Reputation: 3235

c++11 insert a vector into a particular position

I am using c++11, I like to insert a vector into a particular position of another vector, here is a simplified code:

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
    vector<int> v1 = {1, 2, 3}; 

    vector<int> v2 = {0, 3, 9}; 

    vector<int>::iterator itr = find(v2.begin(), v2.end(), 3); 
    itr = v2.erase(itr);

    // like to insert "3", "2" and "1" to the same position which ends up "1", "2" and "3"
    for (auto ri = v1.rbegin(); ri != v1.rend(); ++ri) {
        v2.insert(itr, *ri);
    }   

    for (const auto &i : v2) {
        cout << i << " ";
    }   
    cout << endl;

    return 0;
}

The above code crashes.

Yes, I know some other STL API like transform() or copy() might be the one to use, but just wonder what is wrong of the above code?

Upvotes: 2

Views: 239

Answers (3)

songyuanyao
songyuanyao

Reputation: 172894

what is wrong of the above code?

The iterator itr became invalid after insert, so program crashed at the 2nd execution of the for loop. You can use the return value of insert (iterator pointing to the inserted value) to get a valid iterator for insert position.

Change

v2.insert(itr, *ri);

to

itr = v2.insert(itr, *ri);

insert causes reallocation if the new size() is greater than the old capacity(). If the new size() is greater than capacity(), all iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point remain valid. The past-the-end iterator is also invalidated.

Reference: http://en.cppreference.com/w/cpp/container/vector/insert

PS: Please see @Kam's answer, it's a better solution than hand-written loops in general cases.

Upvotes: 2

Siqi Lin
Siqi Lin

Reputation: 1257

Your current code crashes because itr is invalidated when insert() reallocates v2 after it exceeds its max capacity.

Change the following:

v2.insert(itr, *ri);

to

itr = v2.insert(itr, *ri);

Upvotes: 2

Kam
Kam

Reputation: 6008

Use this API

template <class InputIterator> void insert (iterator position, InputIterator first, InputIterator last);

So in your case, replace the second loop with:

insert(itr,v2.begin(),v2.end())

Upvotes: 2

Related Questions