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
>Solution :
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.