tags:

views:

468

answers:

5

what is the difference between deleting a pointer, setting it to null, and freeing it.

delete ptr;

vs.

ptr=NULL;

vs.

free(ptr);
+16  A: 

delete will give allocated memory back to the C++ runtime library. You always need a matching new, which allocated the memory on the heap before. NULL is something completely different. A "placeholder" to signify that it points to no address. In C++, NULLis a MACRO defined as 0. So if don't like MACROS, using 0 directly is also possible. In C++0x nullptr is introduced and preferable.

Example:

int* a;        //declare pointer
a = NULL;      //point 'a' to NULL to show that pointer is not yet initialized 
a = new int;   //reserve memory on the heap for int

//... do more stuff with 'a' and the memory it points to

delete a;      //release memory
a = NULL;      //(depending on your program), you now want to set the pointer back to
               // 'NULL' to show, that a is not pointing to anything anymore
Lucas
technically, you give it back to the C Runtime library which then may or may not give it back to the OS.
shoosh
@shoosh: Thanks, I edited my post.
Lucas
Actually you give it back to the C++ Runtime library, which may or may not give it back to the C runtime library or OS.
MSalters
@MSalters: Edited, again :)
Lucas
+4  A: 

well, if you created object dynamically(with 'new'), setting pointer to any value does not delete object from memory - and you get a memory leak.

foret
+2  A: 

When you create an object using new, you need to use delete to release its memory back to the system. The memory will then be available for others to reuse.


int* a = new int;
delete a;

NULL is just a pre-defined macro that can be assigned a pointer to mean that it does not point to anything.


int* a = new int;
a = NULL;

In the above case, after allocating storage for a, you are assigning NULL to it. However, the memory previously allocated for a was not released and cannot be reused by the system. This is what we call memory leak.

jasonline
+8  A: 

Your question suggests that you come from a language that has garbage collection. C++ does not have garbage collection.

If you set a pointer to NULL, this does not cause the memory to return to the pool of available memory. If no other pointers point to this block of memory, you now simply have an "orphaned" block of memory that remains allocated but is now unreachable -- a leak. Leaks only cause a program to crash if they build up to a point where no memory is left to allocate.

There's also the converse situation, where you delete a block of memory using a pointer, and later try to access that memory as though it was still allocated. This is possible because calling delete on a pointer does not set the pointer to NULL -- it still points to the address of memory that previously was allocated. A pointer to memory that is no longer allocated is called a dangling pointer and accessing it will usually cause strange program behaviour and crashes, since its contents are probably not what you expect -- that piece of memory may have since been reallocated for some other purpose.

[EDIT] As stinky472 mentions, another difference between delete and free() is that only the former calls the object's destructor. (Remember that you must call delete on an object allocated with new, and free() for memory allocated with malloc() -- they can't be mixed.) In C++, it's always best to use static allocation if possible, but if not, then prefer new to malloc().

j_random_hacker
FTR, this answer was in response to rev 1 of the question: "What's the difference between deleting a pointer and setting it to NULL?"
j_random_hacker
+1 It's also worth pointing out in this new revision that free does not invoke destructors for UDTs and should generally be avoided in C++ (unless one is implementing a memory allocator).
+2  A: 

As with any indirection, there are two objects involved when using pointers: the referrer (the pointer, in your example ptr) and the referenced object (what it points to, *ptr). You need to learn to differentiate between them.

When you assign NULL to a pointer, only the pointer is affected, the object it refers to is left alone. If the pointer was the last one pointing to that object, you have lost the last referring pointer pointing to it and thus cannot use it anymore. In C++, however, that does not mean the object will be deleted. C++ does not have a garbage collection. So the object is leaked.

In order for objects to be deleted, you will have to delete them manually by passing their address (stored in a pointer) to the delete operator. If you do this, only the object referred to will be affected, the pointer is left alone. It might still point to the address where the object resided in memory, even though that isn't usable anymore. That is called a dangling pointer.

sbi
what about free(ptr)
hero
The pointer is not necessarily an object, for example in `delete new int` or `delete function()` or `delete ptr - 1`.
FredOverflow
@hero: You `delete` objects you obtained using `new`, you `delete[]` arrays obtained using `new[]`, you `free()` memory obtained using `malloc()`, etc. However, in C++, you shouldn't use `malloc()`. What it does is to allocate dynamic __memory__, whereas `new` creates dynamically allocated __objects__. In principle, what `new` does is to [allocate memory __and to create the object__ by calling the type's constructor](http://stackoverflow.com/questions/1820069/1820092#1820092).
sbi
@FredOverflow: In C++, an `int` is called an "object", too. I think what you mean is that it doesn't necessarily have to be an lvalue, it could be an rvalue as well.
sbi
@sbi But `int` *values* (such as 42) are not objects, right?
FredOverflow
@FredOverflow: In C++, `42` is a literal (an rvalue) of type `int` and as such it is called "object". An important distinction is made between _lvalues_ and _rvalues_, but, usually, both are called "objects". In C++, "value" and "object" are pretty much synonym, and applied to both built-ins and user-defined types. (In fact, the reason operator overloading was invented was to blur the difference and allow UDTs to be used the same way built-ins are.)
sbi
42 is not an object. Only those rvalues that are of array or class type are objects. All other rvalues aren't objects. (Actually C++03 did miss to say that array rvalues are objects. But that was a defect, and is fixed in the C++0x FCD).
Johannes Schaub - litb
@sbi I wasn't talking about the literal `42`, which is an expression, but about the value 42, which is the result of evaluating the expression `42` ;) lvalues and rvalues are kinds of *expressions*, not kinds of objects. An lvalue of type int is an expression that yields an int object, whereas an rvalue of type int is an expression that yields an int value. (For class types, lvalues and rvalues both yield objects.) If you search the standard for "object representation" and "value representation", you will find that objects and values are not the same thing at all.
FredOverflow
In fact this is why in my other answer i said "std::string() // create one string object" and not "int() // create one int object" because the latter does not create any object :)
Johannes Schaub - litb
@FredOverflow, I've lately been a bit less sure about whether objects are lvalues/rvalues or whether only expressions can be such things. [Temporary objects seem to have such a property](http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#177), even if there is no expression referring to them. I believe though that this is just unfortunate wording. What do you think? Is a FCD comment in order?
Johannes Schaub - litb
@Johannes Current standard §3.10 1 clearly states "Every expression is either an lvalue or an rvalue", and the current draft clearly separates expressions into lvalues, xvalues, prvalues, glvalues and rvalues (see diagram on page 76).
FredOverflow
@FredOverflow i agree so do you think it's a defect introduced by that DR resolution?
Johannes Schaub - litb
@Johannes I think we're getting a little off-topic here ;) Maybe you can ask a separate SO question on this topic, I will be happy to participate once I have polished my standardese a little :)
FredOverflow