13

How do I delete a pointer and the object it's pointing to?

Will the code below delete the object?

Object *apple;
apple = new Object();

delete apple;

And what happens if the pointer is not deleted, and gets out of scope?

Object *apple;
apple = new Object();

This might be a very basic question, but I'm coming from Java.

KaareZ
  • 615
  • 2
  • 10
  • 22
  • 6
    While they share some basic syntax, C++ and Java are very different. You should consider finding a modern book on C++ to learn about it (in modern C++, one would avoid raw memory allocations by using container classes or smart pointers). – crashmstr Nov 19 '15 at 13:51
  • 3
    The pointer is just a variable. You don't have to delete the pointer itself. – Jesper Nov 19 '15 at 13:53
  • 11
    You cannot learn C++ by asking questions on SO, it would take thousands of questions and thousands of days. Get a book. – Jonathan Wakely Nov 19 '15 at 13:53
  • 3
    Here is a list of recommended books: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – Jonathan Wakely Nov 19 '15 at 13:59
  • 1
    It's very similar to Java; when execution reaches the end of the variable's scope the variable ceases to exist, but the object it refers to doesn't. – molbdnilo Nov 19 '15 at 14:05
  • 1
    Why the devotes? I'm just asking a pretty simple question. Not too broad, nor discuss able. – KaareZ Nov 19 '15 at 14:30

5 Answers5

30

Your first code snippet does indeed delete the object. The pointer itself is a local variable allocated on the stack. It will be deallocated as soon as it goes out of scope.

That brings up the second point--if the pointer goes out of scope before you deallocate the object you allocated on the heap, you will never be able to deallocate it, and will have a memory leak.

Hope this helps.

Steve Cobb
  • 781
  • 6
  • 9
7

Hello and welcome to C++ land! You will love how much you hate it (or something like that). C++, while appearing to be similar to java in untrained eyes might look similar, is actually quite different semantically. Lets see how these semantics play out in c++ in regards to your question. First lets take a class:

class Foo {
public:
    Foo() { std::cout << "In constructor\n"; }
    ~Foo() { std::cout << "In destructor\n"; }
};

Foo here is just a representative of any class you might want to use. Lets see what happens when we create and play with a normal Foo object:

{
    Foo bar;
    do_stuff(bar);
}

If we were to run code that looked like this, we would see:

In constructor
In destructor

This is because, when an object is created, it is constructed using the constructor. When it goes out of scope, the destructor is called (~Foo in our code) which deconstructs (or destroys) the object. This is actually a fairly common and powerful feature in C++ (known as RAII, as opposed to other forms of returning memory to the system, such as Garbage Collection). Armed with this new knowledge, lets see what happens when we play with a pointer to Foo:

{
    Foo *bar = new Foo();
    some_more_stuff(bar);
}

What happens here is we would see:

In constructor

This is because of how pointers are allocated versus how variables are allocated. The way pointers are allocated, they don't actually go out of scope normally, but their contents do. This is known as a dangling pointer. For a better example, take a look at this:

#include <iostream>

int* get_int() {
    int qux = 42;
    int *foo = &qux;
    return foo;
}

int main() {
    int *qazal = get_int();
    std::cout << *qazal;
}

Thanks to modern operating systems, this memory will still be returned when the program finishes, but not during the running of the program. If we were to delete the pointer (in the same scope it was created) via delete, then that memory will actually be returned to the operating system at that time.

DTSCode
  • 1,062
  • 9
  • 24
  • Good explanation and I suggest if @KaareZ wants anything more he need to read up on stack and heap memory – CJCombrink Nov 19 '15 at 14:19
  • Thank you :) Its always nice to show people that pointers don't need to be big and scary – DTSCode Nov 19 '15 at 14:21
  • Returning the address of memory allocated on the stack like you have in get_int is dangerous at best. The memory at qux, and by extension, qazal, *could* get overwritten by the call to the cout object's operator<<(), so has undefined behavior. – Nathan Nov 19 '15 at 15:22
  • Yeah I wasn't actually suggesting using a dangling pointer. It is dangerous, and a bad idea. I was just showing him what happens if you don't delete a pointer and scope changes – DTSCode Nov 19 '15 at 15:23
4

When you call delete on a pointer it frees the memory of the thing pointed to. In other words you don't need to free the memory that makes up the pointer variable, just the thing that is pointed to. So your code:

Object *apple;
apple = new Object();

delete apple;

correctly deletes the object and there will be no memory leak.

If you don't call delete and the variable goes out of scope then you'll have a memory leak. These can be difficult to track down, so it's advisable to use a smart pointer class.

Sean
  • 60,939
  • 11
  • 97
  • 136
  • What happens to apple after you delete it? is it then a null pointer such that `if(apple)...` tests to see if the object is still there or not? – Dave X Feb 14 '23 at 19:07
  • 1
    @DaveX - No, the pointer retains it's original value. Any attempt to dereference it is undefined behavior. If you want it to be null then you'll need to explicitly set it to null. – Sean Feb 15 '23 at 08:53
2

Operator delete deletes an object pointed to by the pointer that previously was allocated with operator new.

The pointer itself is not changed and even will have the same value as before the calling the operator. However its value becomes invalid after deleteing the object.

If the pointer itself is a local variable it will be destroyed after the control leaves the declaration region of the pointer.

If the pointer has the static storage duration then it will be destroyed when the program finishes its execution.

Take into account that you can use smart pointers instead of raw pointers.

For example

std::unique_ptr<Object> apple( new Object() );

in this case you need not to call delete It is the smart pointer that will do all the work itself.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Will the code below delete the object?

Yes, it will. But the pointer isn't deleted and accidentally using the pointer after deletion will lead to error.

And what happens if the pointer is not deleted, and gets out of scope?

Memory leak will happen.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70