Search code examples
c++c++11pointersshared-ptrstdset

std::set of shared_ptr's erasing leads to SIGABRT


I have std::set of shared pointers to objects of some type ( ints 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 ) );

Solution

  • 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_ptrs 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?