If you do the following:
ClassType *foo = new ClassType();
ClassType *moo = foo;
delete foo;
And then move along, are there still dangling pointers or not? I thought no, because you only declared one "new", and deleted it, but I want to be sure...
Thanks
You created one object and deleted it.
Both your pointers still point to the memory address that was previously occupied by that object, but the object is deleted, and generally this is the accepted definition of a dangling pointer - one that points to some memory that no longer contains an active object.
There is no memory leak, and your program doesn't cause a problem unless you try to access the now-deleted object through either of your pointers.
Using something like std::shared_ptr or std::unique_ptr may help you manage the memory in a safer way.
In C++, the delete operator calls the destructor of the given argument, and returns memory allocated by new back to the heap. Period. It does nothing more which would mean your pointers that were pointing to a location on the heap, just point to that memory location which has just been de-allocated. So those pointer variables still contain those addresses which it was previously pointing to. This is called 'Dangling pointer'. Now if you assign your - moo and foo to NULL after delete, you will be able to identify if your pointers point to a valid location or NULL easily.
If you mean Dangling pointers, yes the pointers moo and foo are invalid now since it points to something which is already deleted.
foo and moo points on the same dynamic object, created with:
ClassType *foo = new ClassType();
So if you delete foo also moo is 'deleted' or it become an empty pointer.
Related
From my understanding, when you allocate objects on the heap you use
Object* dynamicobject = new Object();
When I call delete I go
delete dynamicobject
I'm confused because I delete the pointer to the instance of that object, but along my line of thinking, you need to actually delete the object in memory itself which requires you to dereference the pointer like
delete *dynamicobject
but this is incorrect.
If you want to change the object a pointer points to, it needs to be dereferenced, and I assumed that the same applied for deletion, but it seems only the pointer can be deleted.
If you do
delete *dynamicobject;
the value given to the delete operator is the value in the dynamic memory location, not the location itself. The delete operator needs to know where the dynamic memory is, so it can reclaim it.
For example, suppose you do:
int *dynamic_int = new int;
*dynamic_int = 10;
If you then did:
delete *dynamic_int;
the delete operator would receive the integer value 10. That doesn't provide the information it needs to reclaim the dynamic memory where that value is stored. But if you do
delete dynamic_int;
the delete operator receives the address of that dynamic memory, and it can reclaim it.
The operators are parallel. new returns a pointer to newly-allocated memory. delete takes a pointer to allocated memory and deletes it. In other words, delete (new ...()) works.
Maybe it would help to consider that delete fundamentally has to work with memory somehow, and not with an object, per se. Thus it needs not only the object but also the object's memory location.
I think you are thinking about destructing the object. When you call new, memory is allocated for the object and its address is returned as a pointer. That pointer is a unique identifier recording exactly which area of memory needs to be deallocated when the object is deleted.
So delete needs to be given the pointer to the memory to deallocate.
But that doesn't kill the object. Killing the object happens by running the destructor and this is where the pointer is dereferenced.
The destructor function is, of course ~Object() {}.
So delete will dereference the pointer to access the actual memory of the object by running the destructor function. After the destructor has run on the dereferenced object the memory address that the object occupied is released back to the runtime system.
So delete needs the pointer which gets dereferenced to destruct the object itself and is then used to determine exactly what memory to release.
delete dynamicobject; does not delete the pointer dynamicobject. Rather, it deletes the object that dynamicobject points to.
You don't have to (and can't) write delete *dynamicobject;, presumably for similar reasons to why you don't have to write dynamicobject = &new Object;.
You only deal in pointers, since dynamic memory allocation is just a big linked list of blocks. When you request a block of size n, the allocator searches the linked list for a block that satisfies the request. When the allocator finds the block, it returns a pointer to said block--that is, the address of the first byte in the block.
Freeing memory simply returns the block into the linked list, so that when you try to allocate memory again, that block may be reused.
All the allocator needs to know is the address of the first byte and the size. That's why it deals only in pointers.
If I have a pointer pointing to a specific memory address at the heap. I would like this same pointer to point to another memory address, should I first delete the pointer? But, in this case am I actually deleting the pointer or just breaking the reference (memory address) the pointer is pointing at?
So, in other words, if I delete a pointer, does this mean it doesn't exist any more? Or, it is there, but not pointing to where it was?
The syntax of delete is a bit misleading. When you write
T* ptr = /* ... */
delete ptr;
You are not deleting the variable ptr. Instead, you are deleting the object that ptr points at. The value of ptr is unchanged and it still points where it used to, so you should be sure not to dereference it without first reassigning it.
There is no requirement that you delete a pointer before you reassign it. However, you should ensure that if you are about to reassign a pointer in a way that causes you to lose your last reference to the object being pointed at (for example, if this pointer is the only pointer in the program to its pointee), then you should delete it to ensure that you don't leak memory.
One technique many C++ programmers use to simplify the logic for when to free memory is to use smart pointers, objects that overload the operators necessary to mimic a pointer and that have custom code that executes automatically to help keep track of resources. The new C++0x standard, for example, will provide a shared_ptr and unique_ptr type for this purpose. shared_ptr acts like a regular pointer, except that it keeps track of how many shared_ptrs there are to a resource. When the last shared_ptr to a resource changes where it's pointing (either by being reassigned or by being destroyed), it then frees the resource. For example:
{
shared_ptr<int> myPtr(new int);
*myPtr = 137;
{
shared_ptr<int> myOtherPtr = myPtr;
*myPtr = 42;
}
}
Notice that nowhere in this code is there a call to delete to match the call to new! This is because the shared_ptr is smart enough to notice when the last pointer stops pointing to the resource.
There are a few idiosyncrasies to be aware of when using smart pointers, but they're well worth the time investment to learn about. You can write much cleaner code once you understand how they work.
When you delete a pointer you release the memory allocated to the pointed to object. So if you just want your pointer to point to a new memory location you should not delete the pointer. But if you want to destroy the object currently it is pointing to and then then point to a different object then you should delete the pointer.
xtofl, while being funny, is a bit correct.
If YOU 'new' a memory address, then you should delete it, otherwise leave it alone. Maybe you are thinking too much about it, but you think about it like this. Yea, the memory is always there, but if you put a fence around it, you need to take the fence down, or no one else can you it.
When you call delete you mark the memory pointed to by the pointer as free - the heap takes ownership of it and can reuse it, that's all, the pointer itself is usually unchanged.
What to do with the pointer depends on what you want. If you no longer need that memory block - use delete to free the block. If you need it later - store the address somewhere where you can retrieve it later.
To answer your question directly, this has been asked before. delete will delete what your pointer points to, but there was a suggestion by Bjarne Stroustrup that the value of the pointer itself can no longer be relied upon, particularly if it is an l-value. However that does not affect the ability to reassign it so this would be valid:
for( p = first; p != last; ++p )
{
delete p;
}
if you are iterating over an array of pointers, all of which had been allocated with new.
Memory management in C++ is best done with a technique called RAII, "resource acquisition is initialization".
What that actually means is that at the time you allocate the resource you immediately take care of its lifetime, i.e. you "manage" it by putting it inside some object that will delete it for you when it's no longer required.
shared_ptr is a technique commonly used where the resource will be used in many places and you do not know for certain which will be the last one to "release" it, i.e. no longer require it.
shared_ptr is often used in other places simply for its semantics, i.e. you can copy and assign them easily enough.
There are other memory management smart pointers, in particular std::auto_ptr which will be superceded by unique_ptr, and there is also scoped_ptr. weak_ptr is a methodology to be able to obtain a shared_ptr if one exists somewhere, but not holding a reference yourself. You call "lock()" which gives you a shared_ptr to memory or a NULL one if all the current shared pointers have gone.
For arrays, you would not normally use a smart pointer but simply use vector.
For strings you would normally use the string class rather than think of it as a vector of char.
In short, you do not "delete a pointer", you delete whatever the pointer points to.
This is a classical problem: If you delete it, and someone else is pointing to it, they will read garbage (and most likely crash your application). On the other hand, if you do not and this was the last pointer, your application will leak memory.
In addition, a pointer may point to thing that were not originally allocated by "new", e.g. a static variable, an object on the stack, or into the middle of another object. In all those cases you're not allowed to delete whatever the pointer points to.
Typically, when designing an application, you (yes, you) have to decide which part of the application owns a specific object. It, and only it, should delete the objects when it is done with it.
Let say I have a hypothetical pointer declared with new like so:
int* hypothetical_pointer = new int;
and create another hypothetical pointer, with the same value:
int* another_hypothetical_pointer = hypothetical_pointer;
If I were to go about deleting these, which were declared with new, would I have to delete both pointers, or only the one explicitly declared with new? Or could I delete either pointer?
delete destroys the dynamically allocated object pointed to by the pointer. It doesn't matter if there are one or 100 pointers pointing to that object, you can only destroy an object once.
After you delete hypothetical_pointer;, you cannot use hypothetical_pointer or another_hypothetical_pointer because neither of them points to a valid object.
If you need to have multiple pointers pointing to the same object, you should use a shared-ownership smart pointer, like shared_ptr, to ensure that the object is not destroyed prematurely and that it is destroyed exactly once. Manual resource management in C++ is fraught with peril and should be avoided.
There is only one block of memory from the single call to new, so you must delete it once and only once, when all users are done with it.
boost::shared_ptr is a nice way to accommodate multiple users of the same data - the last reference going out of scope triggers delete on the underlying memory block.
boost::shared_ptr<int> ptr1(new int);
boost::shared_ptr<int> ptr2(ptr1);
// memory deleted when last of ptr1/ptr2 goes out of scope
Only call delete on one of those pointers - doesn't matter which, since they both contain the same value, as a pointer. Do not use either pointer after calling delete.
Correct answer is that you don't delete either. You delete what they point at.
Now...if they both point at the same thing, how many times do you think you should delete what they point at?
what is the difference between deleting a pointer, setting it to null, and freeing it.
delete ptr;
vs.
ptr=NULL;
vs.
free(ptr);
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().
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
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.
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.
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.
int * ptr = null;
Calling free(ptr) will do nothing. According to standard if given pointer is null then no action happens.
Using delete p will also do nothing. C++ standard says that no action will happen because it points to nothing and no type is available.
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?
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)
Under most circumstances, that will cause a memory leak in your process. You have several options for managing memory in C++.
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.
Use a smart pointer to manage memory for you (auto_ptr, shared_ptr, unique_ptr, etc.)
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.
That is a memory leak. You have to delete memory you allocate manually.
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.
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.
On most modern OSs, the application's memory will be reclaimed at exiting the application. Meanwhile, you have a memory leak.
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.
C++ does't have garbage collector, like some other languages has (Java, C#, ...) so you must delete allocaled objects yourself.
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.
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.
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;
}