The following generates the problem I am having in a larger scale program.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec{1, 2, 3, 4, 5};
for (unsigned i = vec.size() - 1; i >= 0; --i) {
if (vec[i] > 2) vec.erase(vec.begin() + i);
else cout << vec[i] << " ";
}
cout << endl;
return 0;
}
This causes Segmentation fault (core dumped)
.
After a bit debugging, I found that changing the code the following way, "solves" the problem.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vec{1, 2, 3, 4, 5};
for (unsigned i = vec.size() - 1; i >= 1; --i) {
if (vec[i] > 2) vec.erase(vec.begin() + i);
else cout << vec[i] << " ";
}
if (vec[0] > 2) vec.erase(vec.begin());
else cout << vec[0] << " ";
cout << endl;
return 0;
}
This is printing what I expected to get.
2 1
Is not it what the for loop was doing in the first program? I just moved the condition for the beginning of the vector outside the loop!
Also what is the proper way to erase element from vector while iterating like so?
As the comment says, i
is unsigned
, therefore i >= 0
is always true. When i
becomes less than 0
it actually becomes a large positive number, and then indexing into the vector with i
invokes undefined behavior.
The proper way to erase elements from a vector is to use the erase-remove-if idiom:
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int i) {
return i > 2; }), vec.end());