Is It Worth Setting Pointers to Null in a Destructor

Is it worth setting pointers to NULL in a destructor?

Since the destructor is the last thing that is called on an object before it "dies," I would say there is no need to set it to NULL afterwards.

In any other case, I always set a pointer to NULL after calling delete on it.

Do I have to set pointer to nullptr in destructor?


delete[] my_data_;

Should do all you need, after you use this then setting my_data_ to nullptr is not necessary.

Is it good practice to NULL a pointer after deleting it?

Setting a pointer to 0 (which is "null" in standard C++, the NULL define from C is somewhat different) avoids crashes on double deletes.

Consider the following:

Foo* foo = 0; // Sets the pointer to 0 (C++ NULL)
delete foo; // Won't do anything

Whereas:

Foo* foo = new Foo();
delete foo; // Deletes the object
delete foo; // Undefined behavior

In other words, if you don't set deleted pointers to 0, you will get into trouble if you're doing double deletes. An argument against setting pointers to 0 after delete would be that doing so just masks double delete bugs and leaves them unhandled.

It's best to not have double delete bugs, obviously, but depending on ownership semantics and object lifecycles, this can be hard to achieve in practice. I prefer a masked double delete bug over UB.

Finally, a sidenote regarding managing object allocation, I suggest you take a look at std::unique_ptr for strict/singular ownership, std::shared_ptr for shared ownership, or another smart pointer implementation, depending on your needs.

Deleting object vs setting pointer to null

To deallocate an object allocated by new, you should use delete.

To prevent a pointer from being "dangling", set the pointer to nullptr.

Class* c = new Class();
delete c; // free up the allocated memory from new
c = nullptr; // prevent dangling pointer

if c is not used anymore after destruction, assigning it to nullptr is not needed.

An example why a pointer is set to nullptr after delete is because of null guards like:

if (c != nullptr) {
delete c;
c = nullptr;
}

This is redundant since delete already checks if the pointer is still pointing to a valid memory location.

If it is already nullptr, then it does nothing.

From expr.delete#7.3:

Otherwise, the delete-expression will not call a deallocation
function.

[ Note: The deallocation function is called regardless of
whether the destructor for the object or some element of the array
throws an exception. — end note ] If the value of the operand of the
delete-expression is a null pointer value, it is unspecified whether a
deallocation function will be called as described above.

What is the difference between delete a pointer and set the pointer as NULL?

delete myPointer de-allocates memory, but leaves value of myPointer variable, that it is pointing to some garbage address.

myPointer = NULL only sets value of myPointer to null-pointer, possibly leaking memory, if you don't delete other pointer, which points to same address as myPointer

In ideal world you should use both those strings, like this:

delete myPointer; // free memory
myPointer = nullptr; // setting value to zero, signalizing, that this is empty pointer

But overall, use std::unique_ptr, which is modern approach to memory management.

Is there any use in assigning NULL to a pointer after deleting it in destructor in C++?

I see no reason for updating data which is already out of scope, and it is NOT good practice to do things "just in case".
At any rate do not follow "good practices" blindly, it is better to understand why you do things than being the most fervours practitioner of the "good practices" religion.

Do I need to nullify a member variable in the destructor?

In class A, there is absolutely no reason to .clear() the vector-type member variable in the destructor. The vector destructor will .clear() the vector when it is called.

In class B, the cleanup code can simply be written as:

delete p_;

There is no need to test whether p_ != NULL first because delete NULL; is defined to be a no-op. There is also no need to set p_ = NULL after you've deleted it because p_ can no longer be legitimately accessed after the object of which it is a member is destroyed.

That said, you should rarely need to use delete in C++ code. You should prefer to use Scope-Bound Resource Management (SBRM, also called Resource Acquisition Is Initialization) to manage resource lifetimes automatically.

In this case, you could use a smart pointer. boost::scoped_ptr and std::unique_ptr (from C++0x) are both good choices. Neither of them should have any overhead compared to using a raw pointer. In addition, they both suppress generation of the implicitly declared copy constructor and copy assignment operator, which is usually what you want when you have a member variable that is a pointer to a dynamically allocated object.

What's the difference between delete-ing a pointer and setting it to nullptr?

It is not the same, because while you may be setting the pointer to null, the contents that the pointer pointed to would still be taking up space.

Doing

delete pointer;
pointer = NULL;

Is fine, but

pointer = NULL;
delete pointer;

Is not, since you already set the pointer to NULL, the delete command will have nothing to delete (or so it thinks). You now have a memory leak because whatever the pointer pointed to beforehand (let's say a linked list) is now floating somewhere in your memory and is untrackable by the program.

Setting pointer to NULL before delete

Double deleting an object can result in the destructor being called twice, so some people favor setting it to NULL after deletion. This prevents the destructor from being called on memory which could have been reallocated from the pointer's previous memory address.

As shown here though, setting to NULL before deleting is a memory leak. Fixed code without memory leak:

if( m_pio ) {
delete m_pio;
m_pio = NULL;
}

Note that calling delete on NULL (or nullptr in C++11), is legal so you code could just be written as this instead:

delete m_pio;
m_pio = NULL


Related Topics



Leave a reply



Submit