please try to compile and run the following code.
When iterating over a vector of shared pointers, I have to delete last element, this will result in a segmentation fault, but I can't understand why the for
iteration doesn't break when el_it
reaches v.end()
, and I have to do it manually (commented code).
#include <vector>
using std::vector;
#include <memory>
using std::shared_ptr;
#include <algorithm>
using std::remove;
class A {
public:
A(int age) { age_ = age; }
int age_ = 0;
int alive_ = 1;
};
int main() {
shared_ptr<A> a0(new A(0));
shared_ptr<A> a1(new A(1));
shared_ptr<A> a2(new A(2));
vector< shared_ptr <A> > v;
v.push_back(a0);
v.insert(v.end(), a1);
v.insert(v.end(), a2);
for (auto el_it = v.begin(); el_it != v.end(); ++ el_it) {
auto el = *el_it;
if (el->age_ == 2) {
v.erase(el_it);
}
/*
if (el_it == v.end()) // Why is this required ??
break;
*/
}
return 0;
}
Change:
v.erase(el_it);
To
el_it = v.erase(el_it); // don't do this yet, read below
Erasing invalidates iterators. The return value of erase is the valid iterator to the next element. So with what I wrote above you're skipping one element. I'd recommend this:
for (auto el_it = v.begin(); el_it != v.end();) {
auto el = *el_it;
if (el->age_ == 2) {
el_it = v.erase(el_it);
} else {
++ el_it;
}
}