I have std::set
of shared pointers to objects of some type ( int
s here are just for example ). What I need is to insert shared ptr's constructed from raw pointers. But when I'm trying to erase some of set elements ( again I have just a raw pointer ), I should construct shared_ptr
and pass it to erase method ( it seems to me to be true because shared_ptr
's comparison operators compare their raw pointers inside ) .
Code snippet, leading to SIGABRT:
std::set<std::shared_ptr<int>> sett;
int *rp = new int(5);
sett.emplace( rp );
sett.erase( std::shared_ptr<int>( rp ) );
This is not OK:
sett.erase( shared_ptr<int>( rp ) );
Here, rp
is a pointer, so you construct an anonymous temporary shared_ptr
, then you delete the value and memory it points to, then your anonymous temporary deletes it again.
You must not construct two different shared_ptr
s pointing to the same object. If you need something along these lines, you can consider enable_shared_from_this
instead. Or better yet, erase from the container without constructing a shared_ptr
at all, by implementing a comparison function for the std::set
which allows comparing with a raw pointer. For more on that, see: What are transparent comparators?