tags:

views:

602

answers:

11

I was working on a piece of code and I was attacked by a doubt: What happens to the memory allocated to a pointer if I assign NULL to that pointer?

For instance:

A = new MyClass();

{...do something in the meantime...}

A = NULL;

The space is still allocated, but there is no reference to it. Will that space be freed later on, will it be reused, will it remain on stack, or what?

+10  A: 

That is a memory leak. You have to delete memory you allocate manually.

kitchen
+6  A: 

You need to delete A;

For regular objects setting the pointer to NULL does nothing but invalidating the pointer, the object is still around in memory, this is particularly true if you notice that you may have more than one pointer to the same object, changing one shouldn't affect the others.

Arkaitz Jimenez
delete A not free A;
Naveen
Use delete with new, free with malloc. Do not mix these.
Phil Nash
It was a mistake.
Arkaitz Jimenez
I've reversed my downvote following the update
Phil Nash
+3  A: 

On most modern OSs, the application's memory will be reclaimed at exiting the application. Meanwhile, you have a memory leak.

AraK
+2  A: 

No, it will be lost to the process forever. You will have a memory leak. If you keep doing this, your program will eventually run out of memory!! To avoid this, delete the object when you no longer need it.

Often people will set the pointer to NULL after deleting it, so that other parts of the program can verify that the object has been deleted, and thereby avoid accessing or deleting it again.

int3
Not to mention that there's no problem with deleting a null pointer, so if you always set the pointer to 0 after deleting it you'll never double-delete. Just make sure the pointer is non-null before accessing anything through it.
David Thornley
+29  A: 

This is a classic leak. As you say, the memory remains allocated but nothing is referencing it, so it can never be reclaimed - until the process exits.

The memory should be deallocated with delete - but using a smart pointer (e.g. std::auto_ptr or boost::shared_ptr (or tr1::shared_ptr) to wrap the pointer is a much safer way of working with pointers.

Here's how you might rewrite your example using std::auto_ptr:

std::auto_ptr a( new MyClass() );

/*...do something in the meantime...*/

a.reset();

(Instead of the call to reset() you could just let the auto_ptr instance go out of scope)

Phil Nash
If you're only allocating a pointer which you want to keep alive till the end of the scope, a `scoped_ptr` is a better choice.
Pieter
@Pieter, agreed. Arguably in that case std::auto_ptr is almost as good but doesn't require you to bring Boost in if you haven't already done so - although if you have tr1 you can get it from there too
Phil Nash
+3  A: 

As per Phil Nash's comment, for every new, there is a corresponding delete, likewise, for every malloc, there is a corresponding free. If the corresponding delete/free is not there, you have a leak.

Hope this helps, Best regards, Tom.

tommieb75
+2  A: 

C++ does't have garbage collector, like some other languages has (Java, C#, ...) so you must delete allocaled objects yourself.

denisenkom
+23  A: 

Under most circumstances, that will cause a memory leak in your process. You have several options for managing memory in C++.

  1. Use a delete to manually free memory when you're done with it. This can be hard to get right, especially in the context of exception handling.

  2. Use a smart pointer to manage memory for you (auto_ptr, shared_ptr, unique_ptr, etc.)

  3. C++ does not come with a garbage collector, but nothing prevents you from using one (such as the Boehm GC) if you want to go down that route.

Ferruccio
This answer should be upvoted more. +1 for pointing out that you can use third-party garbage collectors with C++
Phil Nash
+1 for pointing out smart pointers.
Sebastian
A: 

By assigning NULL to the pointer you will not free allocated memory. You should call deallocation function to free allocated memory. According to C++ Standard 5.3.4/8: "If the allocated type is a non-array type, the allocation function’s name is operator new and the deallocation function’s name is operator delete". I could suggest the following function to safely delete pointers (with assigning NULL to them):

template<typename T>
inline void SafeDelete( T*& p )
{
    // Check whether type is complete.
    // Deleting incomplete type will lead to undefined behavior
    // according to C++ Standard 5.3.5/5.
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);

    delete p;
    p = NULL;
}
Kirill V. Lyadvinsky
Good point for mentioning the distinction between delete and delete[], but I think the rest is overcomplicating things in the context of the question.
Phil Nash
If I'd only knew about these "overcomplicated" things when I was beginner... :)
Kirill V. Lyadvinsky
So, this handles some of the issues of deallocation safety, but is there any trick to handling the `delete/delete[]` distinction? I can't figure one out off the top of my head, but C++ has lots of deep magic available
Novelocrat
@Kirill, I didn't mean that bringing delete[] up was overcomplicating - just that your templated solution is a little outside the scope (no pun intended) of the original question :-)
Phil Nash
+1  A: 

Variables stored on the stack, are the local variables of each function, e.g. int big[10]; Variables stored on the heap, are the variables which you initiated using explicit memory allocation routines such as malloc(), calloc(), new(), etc.

Variables stored on the stack have a lifetime that is equal to the lifetime of the current stack frame. In English, when the function returns, you can no longer assume that the variables hold what you expect them to hold. That's why its a classic mistake to return a variable that was declared local in a function.

nikifor
+2  A: 
A = new MyClass();

{...do something in the meantime...}

A = NULL;

The way I keep track of it is that there are two separate objects. Somewhere on the heap, a MyClass instance is allocated by new. And on the stack, there is a pointer named A.

A is just a pointer, there is nothing magical about out, and it doesn't have some special connection to the heap-allocated MyClass object. It just happens to point to that right now, but that can change.

And on the last line, that is exactly what happens. You change the pointer to point to something else. That doesn't affect other objects. It doesn't affect the object it used to point to, and it doesn't affect the object (if any) that it is set to point to now. Again, A is just a dumb raw pointer like any other. It might be NULL, or it might point to an object on the stack, or it might point to an object on the heap, or it might be uninitialized and point to random garbage. But that's all it does. It points, it doesn't in any way take ownership of, or modify, the object it points to.

jalf