Calling Delete on Variable Allocated on the Stack

Calling delete on variable allocated on the stack

No, it is not safe to call delete on a stack-allocated variable. You should only call delete on things created by new.

  • For each malloc or calloc, there should be exactly one free.
  • For each new there should be exactly one delete.
  • For each new[] there should be exactly one delete[].
  • For each stack allocation, there should be no explicit freeing or deletion. The destructor is called automatically, where applicable.

In general, you cannot mix and match any of these, e.g. no free-ing or delete[]-ing a new object. Doing so results in undefined behavior.

Deleting an object off the stack?

is it possible to explicitly delete an object that has been initialized on the stack?

No, it is not possible.

According to Paragraph 5.3.5/2 of the C++11 Standard on delete expressions:

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
. [...]

Also relevant is Paragraph 3.7.3/3 about variables with automatic storage duration (i.e. allocated "on the stack"):

If a variable with automatic storage duration has initialization or a destructor with side effects, it shall not
be destroyed before the end of its block
, nor shall it be eliminated as an optimization even if it appears to
be unused, except that a class object or its copy/move may be eliminated as specified in 12.8.

Is `delete ptr;` necessary in destructor even when memory is not dynamically allocated?

delete operator can only be called on objects allocated with new. If you haven't allocated new memory, you cannot call delete operator.

Take the following example:

int main() {
int a = 20;
int* ptr = &a;
delete ptr;
return 0;
}

If you compile this code, it surprisingly(??) compiles without warning.

However, the debugger breaks the code at the call to delete operator.

delete_scalar.cpp:

_CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept {
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK);
#else
free(block);
#endif
}

However, the following code works fine, as the memory has been allocated with new:

int main() {
int* ptr = new int[5];
delete[] ptr;
return 0;
}

Calling delete on address of variable

Your original version does not assign i to an address. It allocates a new int on the heap and initializes its value to 5, then copies that value into i which is on the stack. The memory that you allocated (new'ed) is inaccessible and gets leaked.

The reference version works because i refers to the otherwise-anonymous new'ed memory. Hence &i gives the heap address. In your first version, &i gives the address of the stack variable, not the heap memory, and deleting stack memory is bad news.

is deleting a variable allocated in heap using void pointer a bad thing?

Even though you are using an explicit type conversion, the rules for static_cast apply. The relevant rule is in point 10 of the static_cast page @ cppreference.com:

Conversion of any pointer to pointer to void and back to pointer to the original (or more cv-qualified) type preserves its original value.

In your case, you started with a pointer-to-int. You converted that to pointer-to-void when you initialized ptr. You converted back to pointer-to-int in the delete statement. This preserves the original value, meaning that both (int *)ptr and x evaluate to the same address (and have the same type), hence

delete (int *)ptr;

and

delete x;

are equivalent. (I'd also add

delete static_cast<int*>(ptr);

to the list since getting in the habit of using static_cast et al. instead of a C-style cast could save you headaches in the future.)



Related Topics



Leave a reply



Submit