简体   繁体   中英

Memory leak issue; deleting a pointer

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_ptr s 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.

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", eg 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.

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, ie 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, ie no longer require it.

shared_ptr is often used in other places simply for its semantics, ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM