Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 428
Maddy Avatar asked Mar 21 '16 13:03

Maddy


People also ask

Why do we need Weak_ptr?

By using a weak_ptr , you can create a shared_ptr that joins to an existing set of related instances, but only if the underlying memory resource is still valid. A weak_ptr itself does not participate in the reference counting, and therefore, it cannot prevent the reference count from going to zero.

What is a weak ptr c++?

template< class T > class weak_ptr; (since C++11) std::weak_ptr is a smart pointer that holds a non-owning ("weak") reference to an object that is managed by std::shared_ptr. It must be converted to std::shared_ptr in order to access the referenced object.

Can a Weak_ptr point to a Unique_ptr?

You can implement weak_ptr which works correctly with unique_ptr but only on the same thread - lock method will be unnecessary in this case.

How is Weak_ptr implemented?

To implement weak_ptr , the "counter" object stores two different counters: The "use count" is the number of shared_ptr instances pointing to the object. The "weak count" is the number of weak_ptr instances pointing to the object, plus one if the "use count" is still > 0.


Video Answer


1 Answers

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.

like image 65
Barry Avatar answered Oct 24 '22 22:10

Barry