Reputation: 3235
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
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
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
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