Search code examples
c++smart-pointersobject-lifetimelifetime-scoping

How can I increase ownership count of std::shared pointer


I have a struct that has a pointer as member:

struct MyStruct {
  char *ptr;
}

I want to initialize the ptr in a scope and then be able to use it outside of that scope:

{ // scope 0
    { //scope 1

        { // scope 2
            mystruct.ptr = new char[100];
        }

        // mystruct.ptr still lives here
    }

    // i dont need mystruct anymore
    delete[] mystruct.ptr;
}

But then I have to delete it later, which is error prone and I would rather avoid having to do this. So I thought to use std::shared_ptr.

{ // scope 0
    { //scope 1

        { // scope 2
            auto a = std::make_shared<char>(new char[100]);
            mystruct.ptr = a.get(); // ??????? HOW TO ASSIGN
        }

        // mystruct.ptr still SHOULD live here
    }
}
  • So, how could I do it? How should I assign shared_ptr to mystruct.ptr so that the ownership count becomes 2? I see that get() does not work, because it just passers the pointer but not gives ownership, so it is deleted.

  • As you see, the main motivation here is to extend the lifetime, so I am open to other practices. Maybe I am wrong about thinking in using shared_ptr here?


Solution

  • There is no legal way to increase the ownership-counter of a std::shared_ptr beside assigning it to another std::shared_ptr instance. It would anyway not resolve your problem. In your situation you have to take care of proper new/malloc and free/delete of your used memory. If you manipulate a share_ptr you have to take care that you decrement it too, otherwise you got your memory-leak. It is the same situation.

    • If you have control over the struct MyStruct, change it to a std::string or std::shared_ptr. If not, stick to new/delete IMHO. It is at least readable and honest.
    • If you have control over the scope 0 area, use a std::unique_ptr there. This would make sense as you do not have to take care of exceptions. If you do not know the size needed there, stick to new/delete.