Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the behavior of "delete" with stack objects? [duplicate]

int main()
{
    Class_Name t;
    Class_Name * p = &t;

    delete p;
    return 0;
}  

This code executes fine with 2 destructors being called? How does delete work with stack objects? Is the behavior undefined?

like image 831
sk patra Avatar asked Dec 19 '22 18:12

sk patra


1 Answers

You're running into undefined behavior.

Standard (N3690) 5.3.5[expr.delete]/2

If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.
...

You don't have a null pointer, nor do you have an Object previously allocated with new, so the behavior is undefined.

Note: Even when trying to do

int main()
{
    Class_Name t;
    t.~Class_Name()
    return 0;
}

it would be undefined behavior. Even though it doesn't have a delete in it, simply because it explicitly calls the destructor of an Object with automatic storage duration. Which means that the destructor would be called twice, once when calling it explicitly, the 2nd time when leaving it's scope.

Standard 12.4[class.dtor]/15

Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8). [ Example: if the destructor for an automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined. —end example ]

Most of the time trying to do anything like that would (hopefully) lead to a crash. With a trivial deconstructor you might have (bad) luck and nothing happens though.

Little terminology nitpick here: The C++ standard doesn't talk about stack vs heap objects, it always talks about automatic vs dynamic storage duration respectively. As you can also see in the above quote.


You should always follow the general guideline:

  • For stack allocated objects don't do any explicit freeing/deleting (destructors get called automatically).
  • For each new there should be a corresponding delete
  • For each new[] there should be a corresponding delete[]
  • For each malloc or calloc there should be a corresponding free
like image 96
AliciaBytes Avatar answered Dec 22 '22 08:12

AliciaBytes