20

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?

3
  • 11
    No idea why this was downvoted. It's not worded perfectly, but is surely a valid answer. I wish more newbies were attacked by such doubts and didn't just leave the code with such defects. Commented Nov 24, 2009 at 11:43
  • 4
    @sharptooth: agreed. This might seem a simple question to us gnarly old C/C++ devs, but for someone new to programming, or to non-GC languages this is a perfectly valid question. Commented Nov 24, 2009 at 12:01
  • 2
    " ...will it remain on stack, ...": new does not allocate memory on the stack. Your pointer is on the stack, but not the object itself. It is allocated on the heap. Commented Nov 24, 2009 at 12:05

11 Answers 11

32

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)

Sign up to request clarification or add additional context in comments.

2 Comments

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, 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
24

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.

1 Comment

This answer should be upvoted more. +1 for pointing out that you can use third-party garbage collectors with C++
10

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

Comments

5
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.

Comments

5

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.

1 Comment

Use delete with new, free with malloc. Do not mix these.
3

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

Comments

3

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.

Comments

2

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

Comments

2

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.

1 Comment

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.
1

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.

Comments

0

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; } 

4 Comments

Good point for mentioning the distinction between delete and delete[], but I think the rest is overcomplicating things in the context of the question.
If I'd only knew about these "overcomplicated" things when I was beginner... :)
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
@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 :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.