Home > Back-end >  Shared pointer to a stack variable (C )
Shared pointer to a stack variable (C )

Time:12-27

Following an interview question about the potential issues with a pointer to a stack variable, I went home and played around.

The behaviour I observe is not what I would expect:

std::shared_ptr<Rectangle> createRectangle(double x, double y)
{
    Rectangle r(x, y);
    return std::make_shared<Rectangle>(r);
}

int main()
{
    auto rect = createRectangle(2, 3);
    std::cout << rect->surface() << " " << &rect << std::endl;
}

Surely enough, rectangle r is a stack variable that should be deleted when going out of scope and my smart pointer become dangling, right? Except that the code above works, and outputs:

6 0019FE98

So I tried with a non smart pointer:

Rectangle* createRectangle(double x, double y)
{
    Rectangle r(x, y);
    return &r;
}

There I got an undefined output value as expected:

-4.62798e 62 0019FEA8

A bit puzzled I went on to read about the issue and realized that there was a secondary problem I didn't think about initially: if the smart pointer goes out of scope before the object, then the object will be deleted (unless an empty deleter is passed when creating the pointer like suggested in the answer). Without the empty deleter, the following code should be problematic I dared to think:

std::shared_ptr<Rectangle> createRectangle(double x, double y)
{
    Rectangle r(x, y);
    if (true) {
        auto rectPtr = std::make_shared<Rectangle>(r);
    }
 
    return std::make_shared<Rectangle>(r);
}

The rectPtr should invoke the deleter on the object after the if block and the object be cleaned from memory, right? But no problem, the output is clean and the value returned.

None of the behaviour I observed with the shared_pointer was what I was expecting.

Can someone please explain me what I am missing? Is my understanding incorrect? Are there some compiler optimizations that are leading the variable pointed to, not to be deleted when we would expect?

Many thanks

CodePudding user response:

You don't create a pointer to the variable r, instead you create a copy of it.

Doing

return std::make_shared<Rectangle>(r);

is essentially equivalent to doing

return std::shared_ptr<Rectangle>(new Rectangle(r));

This will copy-construct a new Rectangle object as a shared pointer, and return that shared pointer.

CodePudding user response:

make_shared internally allocates the object on the heap and passes your stack variable to its constructor. So your shared pointers point to a heap-allocated copy of r.

To create a shared ptr to the stack variable r use this: return shared_ptr(&r);

Edit: Some programmer dude was faster (great name btw), but I'm leaving this up because it contains the correct call you need for your experiment.

  •  Tags:  
  • c
  • Related