1

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?

laurisvr
  • 2,724
  • 6
  • 25
  • 44
Mert Mertce
  • 1,614
  • 3
  • 21
  • 32
  • 1
    You'd "extend the ownership" to `mystruct.ptr` by making that a shared pointer (or unique pointer, unless you specifically need to share ownership). That's how shared pointers work. There's no way to get automatic ownership semantics from a raw pointer. – Mike Seymour May 20 '15 at 09:20
  • I can not modify mystruct. So with a raw pointer I have to use new-delete? – Mert Mertce May 20 '15 at 09:23
  • 1
    Yes. That's why you shouldn't use raw pointers to represent ownership of a dynamic resource. If you really can't fix it for some reason, then you'll have to carefully delete it yourself. Or arrange for something else to own it, and live as long as the evil pointer. – Mike Seymour May 20 '15 at 09:25
  • Why not hold `mystruct` itself in a smart pointer, with a custom deleter to free the char array? – StoryTeller - Unslander Monica May 20 '15 at 09:31
  • Related question: [Manually incrementing and decrementing a boost::shared_ptr?](https://stackoverflow.com/questions/1482806/manually-incrementing-and-decrementing-a-boostshared-ptr) – Gabriel Devillers Aug 21 '23 at 15:55

1 Answers1

5

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.
Martin Schlott
  • 4,369
  • 3
  • 25
  • 49
  • *There is no legal way to increase the ownership-counter* fortunately :-) otherwise: who would care for decreasing it? It looks a lot like a case for `std::string`. – Wolf May 20 '15 at 09:59
  • It would be a kind of (not exisiting) std::manual_ptr where the developer has to increment and decrement the counter. I saw that in Objective C and MS COM. It does not work reliable, because developer can forget the release command as they can forget to free memory. – Martin Schlott May 20 '15 at 10:03
  • I had thought as if when mystruct goes out of scope, automatically would drop its ownership to the ptr. But now I see that since it is a raw pointer, still I had to maintain it, so better use delete. – Mert Mertce May 20 '15 at 10:06
  • @MartinSchlott Really? I'm shocked. BTW: in this question isn't clear what the extra scopes are for: maybe to prevent auto pointers from escaping? – Wolf May 20 '15 at 10:09
  • @Wolf good to try to be funny, but of course unnecessary stuff is omitted to show the core of the question. MikeSeymour and MartinSchlott well understood and answered. – Mert Mertce May 20 '15 at 10:15
  • @MertMertce Would `std::auto_ptr` be an option? It has the [release](http://www.cplusplus.com/reference/memory/auto_ptr/release/) method. – Wolf May 20 '15 at 10:29
  • @MertMertce, Martin Schlott, ok then it seems to be [unique_ptr](http://en.cppreference.com/w/cpp/memory/unique_ptr) that would help in the inner scope. – Wolf May 20 '15 at 10:35