Calling delete on variable allocated on the stack

C++StackHeap MemoryDelete Operator

C++ Problem Overview


Ignoring programming style and design, is it "safe" to call delete on a variable allocated on the stack?

For example:

   int nAmount;
   delete &nAmount;

or

class sample
{
public:
    sample();
    ~sample() { delete &nAmount;}
    int nAmount;
}

C++ Solutions


Solution 1 - C++

https://msdn.microsoft.com/en-us/library/h6227113(v=vs.140).aspx">No</a>;, 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.

Solution 2 - C++

Well, let's try it:

jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy@jeremy-desktop:~$ g++ -o test test.cpp
jeremy@jeremy-desktop:~$ ./test
Segmentation fault

So apparently it is not safe at all.

Solution 3 - C++

Keep in mind that when you allocate a block of memory using new (or malloc for that matter), the actual block of memory allocated will be larger than what you asked for. The memory block will also contain some bookkeeping information so that when you free the block, it can easily be put back into the free pool and possibly be coalesced with adjacent free blocks.

When you try to free any memory that you didn't receive from new, that bookkeeping information wont be there but the system will act like it is and the results are going to be unpredictable (usually bad).

Solution 4 - C++

Yes, it is undefined behavior: passing to delete anything that did not come from new is UB:

> C++ standard, section 3.7.3.2.3: > The value of the first argument supplied to one of thea deallocation functions provided in the standard library may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_t&) in the standard library.

The consequences of undefined behavior are, well, undefined. "Nothing happens" is as valid a consequence as anything else. However, it's usually "nothing happens right away": deallocating an invalid memory block may have severe consequences in subsequent calls to the allocator.

Solution 5 - C++

After playing a bit with g++ 4.4 in windows, I got very interesting results:

  1. calling delete on a stack variable doesn't seem to do anything. No errors throw, but I can access the variable without problems after deletion.

  2. Having a class with a method with delete this successfully deletes the object if it is allocated in the heap, but not if it is allocated in the stack (if it is in the stack, nothing happens).

Solution 6 - C++

Nobody can know what happens. This invokes undefined behavior, so literally anything can happen. Don't do this.

Solution 7 - C++

No, Memory allocated using new should be deleted using delete operator and that allocated using malloc should be deleted using free. And no need to deallocate the variable which are allocated on stack.

Solution 8 - C++

An angel loses its wings... You can only call delete on a pointer allocated with new, otherwise you get undefined behavior.

Solution 9 - C++

here the memory is allocated using stack so no need to delete it exernally but if you have allcoted dynamically

like int *a=new int()

then you have to do delete a and not delete &a(a itself is a pointer), because the memory is allocated from free store.

Solution 10 - C++

You already answered the question yourself. delete must only be used for pointers optained through new. Doing anything else is plain and simple undefined behaviour.

Therefore there is really no saying what happens, anything from the code working fine through crashing to erasing your harddrive is a valid outcome of doing this. So please never do this.

Solution 11 - C++

It's UB because you must not call delete on an item that has not been dynamically allocated with new. It's that simple.

Solution 12 - C++

Motivation: I have two objects, A and B. I know that A has to be instantiated before B, maybe because B needs information calculated by A. Yet, I want to destruct A before B. Maybe I am writing an integration test, and I want server A to shut-down first. How do I accomplish that?

A a{};
B b{a.port()};

// delete A, how?

Solution: Don't allocate A on the stack. Instead, use std::make_unique and keep a stack-allocated smart pointer to a heap-allocated instance of A. That way is the least messy option, IMO.

auto a = std::make_unique<A>();
B b{a->port()};

// ...

a.reset()

Alternatively, I considered moving the destruction logic out of A's destructor and calling that method explicitly myself. The destructor would then call it only if it has not been called previously.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionunistudentView Question on Stackoverflow
Solution 1 - C++Mr FoozView Answer on Stackoverflow
Solution 2 - C++Paige RutenView Answer on Stackoverflow
Solution 3 - C++FerruccioView Answer on Stackoverflow
Solution 4 - C++Sergey KalinichenkoView Answer on Stackoverflow
Solution 5 - C++SambatyonView Answer on Stackoverflow
Solution 6 - C++user529758View Answer on Stackoverflow
Solution 7 - C++VinayView Answer on Stackoverflow
Solution 8 - C++Luchian GrigoreView Answer on Stackoverflow
Solution 9 - C++AshrithView Answer on Stackoverflow
Solution 10 - C++GrizzlyView Answer on Stackoverflow
Solution 11 - C++Martin JamesView Answer on Stackoverflow
Solution 12 - C++user7610View Answer on Stackoverflow