Custom Deleters of Shared & Unique Pointer

Summary

In this post, I will introduce custom deleters when using C++ std::shared_ptr and std::unique_ptr.

Conclusion

Use the following snippets. Note the fourth case, where a unique_ptr with custom deleter will not pass the deleter to the shared_ptr when using release().

class OldThing {
  public:
    ~OldThing() 
    {
      if (allocated_) {
        std::cout << "MEMORY LEAK!" << std::endl;
      }
    }
    void Deallocate()
    {
      std::cout << "Deallocate called." << std::endl;
      allocated_ = false;
    }
  private:
    bool allocated_{ true };
};
int main() { 
  {
    OldThing oldThing;
    // oldThing going out of scope causes a "memory leak"
  }

  {
    // shared_ptr's constuctor handles the deleter
    std::shared_ptr<OldThing> p(new OldThing, 
      [] (OldThing* ot) {
        ot->Deallocate();
        delete ot;
      }
    );
  }

  {
    // We need to include the deleter's type in the template parameters:
    std::unique_ptr<OldThing, void(*)(OldThing*)> p(new OldThing, 
      [] (OldThing* ot) {
         ot->Deallocate();
         delete ot;
      }
    );
  }

  {
    // !!! memory leak!!!
    std::unique_ptr<OldThing, void(*)(OldThing*)> p(new OldThing, 
      [] (OldThing* ot) {
         ot->Deallocate();
         delete ot;
      }
    );
    auto p_ = std::shared_ptr<OldThing>(p.release());
  }

  {
    // works, shared_ptr receives the deleter from unique_ptr
    std::unique_ptr<OldThing, void(*)(OldThing*)> p(new OldThing, 
      [] (OldThing* ot) {
         ot->Deallocate();
         delete ot;
      }
    );
    std::shared_ptr<OldThing> p_ = std::move(p);
  }

  return 0;
}

The result will be

MEMORY LEAK!                                                                                                                                                                       
Deallocate called.                                                                                                                                                                 
Deallocate called.                                                                                                                                                                 
MEMORY LEAK!                                                                                                                                                                       
Deallocate called.   

Leave a Reply

Your email address will not be published. Required fields are marked *