#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> a = {1,2,3,7,1,5,4};
vector<int> b = {6,7,4,3,3,1,7};
a.erase(remove(a.begin(),a.end(),a[0]),a.end());
b.erase(remove(b.begin(),b.end(),b[0]),b.end());
return 1;
}
For this specific example, my GNU gdb Ubuntu 7.7.1 states that at return 1 line: a = {2,3,7,1,5,4} which is not expected (only deletes one 1), and b = {7,4,3,3,1} which is not expected.
My expectation is b should be a=2,3,7,5,4 and b=7,4,3,3,1,7.
What's happening here?
The C++ vector has many member functions. Two of these member functions are erase() and pop_back(). pop_back() removes the last element from the vector. In order to remove all the elements from the vector, using pop_back(), the pop_back() function has to be repeated the number of times there are elements.
All the elements of the vector are removed using clear() function. erase() function, on the other hand, is used to remove specific elements from the container or a range of elements from the container, thus reducing its size by the number of elements removed.
The declaration of std::remove()
looks like
template <class ForwardIterator, class T>
ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& val);
Note that the last parameter is a reference. Thus after compilation it effectively pass the address of the specified element.
By remove(a.begin(), a.end(), a[0])
, something indicating the address to the 0th element of a
is passed in. When remove()
is running, once the 0th element is handled, the value pointed by the reference passed in changed, which leads to the unexpected result.
To get expected result, make a copy before calling std::remove()
.
int toberemoved = a[0];
a.erase(remove(a.begin(),a.end(),toberemoved),a.end());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With