How to intentionally delete a boost::shared_ptr?

54,695

Solution 1

You just do

ptr.reset();

See the shared_ptr manual. It is equivalent to

shared_ptr<T>().swap(ptr)

You call reset on every smart pointer that should not reference the object anymore. The last such reset (or any other action that causes the reference count drop to zero, actually) will cause the object to be free'ed using the deleter automatically.

Maybe you are interested in the Smart Pointer Programming Techniques. It has an entry about delayed deallocation.

Solution 2

If you want to be able to intentionally delete objects (I do all the time) then you have to use single ownership. You have been lured into using shared_ptr when it is not appropriate to your design.

Solution 3

The whole point of boost::shared_ptr<T> is that the pointee object will be deleted exactly at the moment when no shared_ptr<T>s point at it -- that is, when the last shared_ptr<T> pointing at this object goes out of scope or is reassigned to point to a different object. So, all you have to do to delete an object is make sure there are no shared_ptr<T>s pointing at it. E.g. if you only have a single shared_ptr<T> called p pointing at an object, either let it fall out of scope, or call p.reset() (equivalent to p = NULL for a plain pointer), or assign it to point at something else.

If you have two shared_ptr<T>s pointing at the object, you'll need to reassign both of them.

EDIT: Thanks to dehmann for pointing out that p = NULL; is not actually valid code for a shared_ptr<T>... :)

Solution 4

What you want to do is return weak references using boost::weak_ptr that can be converted to a shared_ptr when needed. This can allow you to control the lifetime of the object in the shared_ptr and those that want to access it can hold onto the weak_ptr and try to convert to a shared_ptr. If that convert fails, then they can re-query and bring the object back into memory.

Share:
54,695

Related videos on Youtube

Frank
Author by

Frank

Updated on August 24, 2020

Comments

  • Frank
    Frank over 3 years

    I have many boost::shared_ptr<MyClass> objects, and at some point I intentionally want to delete some of them to free some memory. (I know at that point that I will never need the pointed-to MyClass objects anymore.) How can I do that?

    I guess you can't just call delete() with the raw pointer that I get with get().

    I've seen a function get_deleter(shared_ptr<T> const & p) in boost::shared_ptr, but I'm not sure how to use it, and also it says experimental right next to it. (I think I have Boost 1.38.)

    Maybe just assign a new empty boost::shared_ptr to the variable? That should throw away the old value and delete it.

    • Martin York
      Martin York about 15 years
      NOOOOO: Don't call delete after a call to get(). The smart pointer still has a copy and will call delete when it releases the object.
  • Frank
    Frank about 15 years
    Sounds good, but one thing: You can't write p=NULL, because p is a shared_ptr, not a pointer.
  • m-sharp
    m-sharp about 15 years
    Yes, for a related question on how to use NULL when using shared_ptrs, see stackoverflow.com/questions/621220/…
  • Ankit Roy
    Ankit Roy about 15 years
    @m-sharp: Thanks for the link. I added an answer on that thread that allows a natural "p = nullPtr;" syntax to be used for any shared_ptr<T> type.
  • jiggunjer
    jiggunjer almost 9 years
    so why isnt p = nullptr syntax allowed? it seems pretty intuitive, more so than reset()...
  • Ankit Roy
    Ankit Roy almost 9 years
    @jiggunjer: I don't know, but I do know that smart pointers arrived a long time before the keyword nullptr was part of the C++ language. Allowing p = nullptr in addition seems like it could do no harm... But then a lot of things seem that way in C++ at first :-/