Search code examples
c++shared-ptrweak-ptr

What happens to an expired weak_ptr in a map


I would like to understand what happens to an entry (of type boost::weak_ptr) in a map whose weak_ptr has expired. Does the corresponding entry in the map get automatically deleted?

The key is an integer and corresponding value is a weak_ptr.

Sample code I wrote, but could not get it to compile

    #include <iostream>
    #include <map>
    #include <boost/enable_shared_from_this.hpp>

    using namespace std;

    class Foo : public boost::enable_shared_from_this<Foo> {
    public:
        Foo(int n = 0) : bar(n) {
            std::cout << "Foo: constructor, bar = " << bar << '\n';
        }
        ~Foo() {
            std::cout << "Foo: destructor, bar = " << bar << '\n';
        }
        int getBar() const { return bar; }
        boost::shared_ptr<Foo> inc_ref() {
            return shared_from_this();
        }
    private:
            int bar;
    };

    std::map<int, boost::weak_ptr<Foo> > mappy;

    int main()
    {
        boost::shared_ptr<Foo> sptr(new Foo(1));

        std::pair<std::map<int, boost::weak_ptr<Foo> >::iterator, bool> res = 
mappy.insert(std::make_pair(10, sptr));

        if (!res.second ) {
            cout << "key already exists "
                             << " with value " << (res.first)->second << "\n";
        } else {
            cout << "created key" << "\n";
        }

        std::cout << "sptr use count  "<< sptr.use_count() << '\n';

        sptr.reset();

        std::cout << "sptr use count  "<< sptr.use_count() << '\n';

        std::map<int, boost::weak_ptr<Foo>, std::less<int> >::iterator map_itr = mappy.find(10);
        if (map_itr == mappy.end()) {
            cout << "Entry removed" << "\n";
        } else {
            cout << "Entry found: " << map_itr << "\n";
        }

        return 0;
    }

The documentation of WeakSet in Java says that the entry is removed when the weak_ptr expires. So thought of checking if the map exhibits a similar (or undefined) behavior.

Thanks!


Solution

  • Does the corresponding entry in the map get automatically deleted?

    No, it doesn't. The entry will continue to exist. The map and the shared_ptr are entirely unrelated entities. All the destruction of the last shared_ptr does is free memory.

    The advantage of weak_ptr is that the weak_ptr will be able to know if the shared_ptr has been deleted or not. That's what the expired() and lock() member functions are for. Once it's expired though, it is still up to you to remove it from the map.