Reputation: 159
I have 2 std::lists. I want to delete all the items from list 1 and insert it in the 2nd and vice versa. My code is not working (getting access violation and "list iterator not dereferencable")
for ( std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it ) {
it = list1.erase( it );
list2.push_back( *it );
}
it = list1.begin();
it = list2.erase( it ); // because the last element is not deleted in the above loop
list2.push_back( *it );
Symmetrical code for the 2nd method. I manage to transfer the items between the 2 lists one time, but the next I get the error.
Any help?
Upvotes: 1
Views: 324
Reputation: 3571
Of course you have to use list::swap
.
But your code show you have some misunderstanding.
for ( std::list<Item *>::iterator it = list1.begin(); it != list1.end(); ++it ) {
it = list1.erase( it ); // this effectively erase and destroy *it,
// and erase() return an iterator to the NEXT element.
// Now it=it+1
list2.push_back( *it ); // you copy the NEXT element!!
// here is where we efectively get the ++it of the 'for'.
// When erase was used when ‘it’ was at end()-1, erase return end()
// The attempt to do it=end()+1 is an error probably detected by an assertion.
}
If list1
have originally even number of elements, for example 0,1,2,3,4,5,6,7,8,9 the iterator end()
will point to the inexistent 10, with you don’t need (cant) erase. This ‘for
’ will delete the even elements (0,2,4,6,8) , and copy to list2
the odd (1,3,5,7,9). But if originally list1
have odd elements, for example 0,1,2,3,4,5,6,7,8 the last deleted is 8, erase
return an iterator to the inexistent 9 = end(),
and the ‘for’ make an attempt to increment it with don’t pass the assertion.
Upvotes: 0
Reputation: 227468
This is easily and efficiently done with std::list
's swap
member function:
list1.swap(list2);
This has constant time complexity.
Upvotes: 3