-1

Suppose I have a method that defines a shared_ptr. After the method finishes, the shared_ptr will also be deleted. In the interim I have another member that uses that shared_ptr. So I would like to extend the lifetime of the shared_ptr past the initial method.

void initial_method(int input)
{
  std::shared_ptr<int> a { std::make_shared<int>(input) };
  some_delayed_method(a);
}

Is it possible to manually increase the reference count of a by one in this example?

some_delayed_method() is like a detachment and is referring to a at a time after the initial_method() has returned.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • 1
    You don't have to do this. The `std::shared_ptr` is valid for the duration of the method call. – Mansoor Oct 27 '20 at 22:39
  • 1
    Simply making a copy of the shared_ptr should be sufficient to extend the lifetime of the `int` it is pointing to, is that what you had in mind? – Jeremy Friesner Oct 27 '20 at 22:55
  • Please [edit] your question and clarify what the problem is: I see that at least two people (myself included) misunderstood it. Maybe show more of your code. Maybe add some print-statements which show where the problem is. – anatolyg Oct 28 '20 at 09:01
  • @OS2 You editted your question which completely changes its scope! In any case, you should show the code for the some_delay_method. – Mansoor Oct 28 '20 at 09:01
  • Does this answer your question? [How to release pointer from boost::shared\_ptr?](https://stackoverflow.com/questions/1525764/how-to-release-pointer-from-boostshared-ptr) – anatolyg Oct 29 '20 at 08:45

2 Answers2

2

Since you can't call some_delayed_method without a shared_ptr to the object and any shared_ptr to the object extends its lifetime, there is nothing you need to do.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    @OS2 I read it again and stand by this answer. Whatever code calls `some_delayed_method`, whenever and however it calls it, must hold `std::shared_ptr` to `a` which keeps it around already. – David Schwartz Oct 28 '20 at 17:43
-1

If some_delayed_method saves the pointer in some external data structure, and this pointer will later be used, you should use shared_ptr for that.

class X
{
public:
    void initial_method(int input)
    {
        std::shared_ptr<int> a { std::make_shared<int>(input) };
        some_delayed_method(a);
    }

    void some_delayed_method(const std::shared_ptr<int>& a)
    {
        use_later = a;
    }

private:
    std::shared_ptr<int> use_later;
}

This way, the reference count will be handled automatically.


You may insist on using a raw pointer to save the data for later:

void some_delayed_method(const std::shared_ptr<int>& a)
{
    use_later = a.get();
}

...

int* use_later;

This is not a proper way to save the data. To make it work (or appear to work), you have to do some hack. For example, make another reference to the data, and leak it:

void some_delayed_method(const std::shared_ptr<int>& a)
{
    use_later = a.get();
    new std::shared_ptr<int>(a); // horrible hack; please never do it! but it works...
}

This hack leaks the allocated std::shared_ptr so it can never be deleted, thus its refcount is not decremented and the allocated int is leaked.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
  • The "hack" indeed leaks the `new`ly allocated `std::shared_ptr` so it can never be `delete`d, thus the refcount of the allocated `int` is not decremented and it is leaked, too. – Remy Lebeau Oct 27 '20 at 23:15
  • Thanks for the description of how it works! I forgot to mention that the `int` object itself is leaked. – anatolyg Oct 27 '20 at 23:19
  • OK thanks. I was looking for a way to not have to make a second copy. At this rate, I might as well just use a raw pointer (new delete) instead. –  Oct 27 '20 at 23:27
  • This `use_later = a;` has be carried out before the call to `some_delayed_method()`. I might as well use a raw pointer. –  Oct 27 '20 at 23:33
  • Why are you suggesting to deliberately leak memory... with a smart pointer of all things? – Passer By Oct 28 '20 at 03:27
  • @OS2 Don't forget that you have the option of using `shared_ptr` to store the additional reference, as I described in the first part of my answer. This is the proper solution, without hacks. – anatolyg Oct 28 '20 at 05:46
  • @anatolyg Your second point isn't even obvious so IDK why you'd bring it up. The question remains unanswered. –  Oct 28 '20 at 08:54