-1

I am currently refactoring some old parts of a code. The method I am working on is heavily using the new and delete features in order to achieve its purpose. I could easily replace all that with shared pointers for better code clarity and safety. The thing is, that in the end I need to return a pointer to an allocated memory to match the API. This wont work with shared pointers.

I could just allocate a new memory block with new and copy the contents of the memory allocated by shared_ptr (my first idea). But then I thought maybe there is a mechanism for telling the shared_ptr to not to free the allocated memory on context loosing? This way I could return the pointer to the allocated memory by shared ptr without free'ing it.

halfer
  • 19,824
  • 17
  • 99
  • 186
Łukasz Przeniosło
  • 2,725
  • 5
  • 38
  • 74
  • This answer seems to solve your problem: https://stackoverflow.com/questions/1833356/detach-a-pointer-from-a-shared-ptr/5995770#5995770 – selalerer Sep 08 '19 at 14:04

2 Answers2

5

If you were to replace the new with std::unique_ptr instead, you could use std::unique_ptr::release to get ownership over a raw pointer (so you can return it):

T* oldfn() {
    T* ptr = new T(args...);
    // use `ptr`
    delete ptr;
    T* ptr2 = new T(args...);
    // use `ptr2`
    return ptr2;
}

// Becomes

T* newfn() {
    std::unique_ptr<T> ptr{ new T(args...) };
    // use `ptr.get()`
    // RAII will delete
    std::unique_ptr<T> ptr2{ new T(args...) };
    // use `ptr2.get()`
    return ptr2.release();
}

You cannot do this easily with a shared pointer because the shared pointer itself doesn't own the pointer on it's own, since you can make copies of the shared pointer that point to the same resource, so releasing ownership through one pointer is hard.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Artyer
  • 31,034
  • 3
  • 47
  • 75
  • Great solution. In Qt world thats `QSharedPointer` (`shared_ptr`) and `QScopedPointer` (`unique_ptr`). You helped me realize that I should use unique pointers way often instead of shared pointers, since unique are enough for the job (and like here, can give away ownership). Thanks! – Łukasz Przeniosło Sep 08 '19 at 14:05
2

But then I thought maybe there is a mechanism for telling the shared_ptr to not to free the allocated memory

There is: The method is to keep at least one shared pointer pointing to it.

If your API does not let you return a shared pointer, but rather forces you to transfer ownership through a bare pointer, then using shared ownership in the first place is not a good idea. I would recommend against it.

If you want to take ownership away from the shared pointer so that the allocation won't be deleted even after the last shared pointer, you technically can use a custom deleter that allows transfer of the ownership. This approach however is quite dangerous if there are multiple shared pointers still pointing to the resource, since it would not be easy to guarantee that the resource is no longer needed by them.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Thank you for answer. I thought of working around this using custom deleter (that would actually not delete anything), but it seemed a bit hacky. Thank you for the explanation though. – Łukasz Przeniosło Sep 08 '19 at 14:06