0

Main function code:

PNG* allocate(size_t w, size_t h) {
    PNG ret(w, h);
    return &ret;
}

int main() {
    PNG * image = allocate(256, 512);
    delete image;
    return 0;
}

Assume that appropriate PNG class is defined. My question is about allocate(); and &ret. Usually after functions are called, every created instance is cleared (only data are newly copied). In this case &ret points to the location of the newly create ret. But it seems that after function is run, ret will be deleted, and as a result, PNG * image will behave wildly.

Is this true? If so, what would be the way to fix the code?

Also, image is not created by new, so would it be sensible to use delete?

Quentin
  • 62,093
  • 7
  • 131
  • 191

2 Answers2

2

To answer your question literally, the way to fix this code is to not call delete on any pointer that was not given to you as a result of calling new.

delete does two things:

  1. It calls the object's destructor
  2. It releases the memory for the object back to the runtime's allocator

In this instance the ret object created within allocate will be automatically destroyed when the function exits, so there is no point in trying to call its destructor. That object was also not allocated on memory provided by the runtime, so it's also meaningless to talk about releasing that memory.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • What about &ret? Is there nothing wrong with this? – uzawa laoma Jan 22 '15 at 23:05
  • @uzawalaoma: Technically there is nothing wrong with *returning* that value, but if you try to do *almost anything* with it then that is undefined behavior (the definition of "wrong" if there ever was one). So you can assign the returned value to `image`, but you are not allowed to use it for anything. – Jon Jan 22 '15 at 23:07
  • @uzawalaoma `return &ret` where ret is an object on the stack is almost certainly not what you meant to do, because anything reading the return value will most likely end up with garbage. – Steve Lorimer Jan 22 '15 at 23:13
0

You're returning the memory address of a function local object (a temporary), which means it has been created on the stack.

When the function returns, the object will be deleted automatically (when it is popped off the stack)

It is undefined behaviour to access this object after the function has returned, because you're now reading memory which is no longer allocated to the object.

The only time you should use delete is when you've allocated memory on the heap (by using new)

Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213