Why Doesn't Delete Set the Pointer to Null

Why doesn't delete set the pointer to NULL?

Stroustrup himself answers. An excerpt:

C++ explicitly allows an
implementation of delete to zero out
an lvalue operand, and I had hoped
that implementations would do that,
but that idea doesn't seem to have
become popular with implementers.

But the main issue he raises is that delete's argument need not be an lvalue.

Why pointer is not NULL after using delete in C++

It's because when you say delete p you're deleting a pointer to memory which completely erases the reference to the new memory you allocated. When you say if p==NULL you're checking to see if the pointer was set to null when in fact the memory that it was pointing to was de-allocated so the pointer isn't pointing to anything. Which doesn't mean the same as having it point to NULL in C++.

Why C++ delete operator doesn't set pointer to NULL?

No, there's no real use to leaving it set to the original value, other than showing how inept people are at writing code :-)

It follows the traditions of C in that you're expected to know what you're doing. The cost of having the compiler set freed pointers to NULL was deemed too high in the C days and this has carried over to C++ with delete. If you code properly, then having the compiler set the pointer to NULL is a waste, since you'll either set it to something else or not use it again.

If you really want to make your code safer, you'd do something like (in C):

void myFree (void **pMem) {
free (**pMem);
*pMem = NULL;
}
myFree (&x);

instead of just:

free (x);

But, if you're going to go to that level (and introduce such an abomination), just switch to Java and be done with it, then you don't have to concern yourself with manual memory management at all.

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.

Why is it recommended to set a pointer to null after deleting it?

Just so that you know the pointer does not point to anything anymore, and will fail if conditions and other boolean checks:

   delete ptr;
ptr = NULL;
if(ptr)
*ptr = 2;

This code will run perfectly fine, although it would cause memory corruption if the pointer was not set to NULL.

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.

Why compilers do not assign NULL to pointer variable automatically after deleting dynamic allocated memory?

  1. It would often be unnecessary, particularly in well-written code.

  2. It could hide away bugs.

  3. delete p; would be syntactically idiosyncratic if it modified its argument.

On (1) it would be particularly wasteful with std::unique_ptr.

In other words, burdening the programmer with this job if necessary is the right thing to do.

C++ - Why set object to null after deleting?

It's unnecessary. Some people make a habit of doing this even when it has no result. An aggressive compiler optimizer will eliminate this code, so it doesn't actually do any harm. But I would have written:

void DeleteAfter(Node *head) {
if (head) {
Node *next = head->next;
if (next) {
head->next = next->next;
delete next;
}
}
}

Note I eliminated a useless level of indirection and added a check to make sure there's a "node after" to delete.

The rationale for the habit is that if a pointer always refers to either a valid object or is null, you can rely on null checks as equivalent to validity checks.

For this reason, Ada, a language often used in safety critical systems, initializes pointers to null and defines its delete equivalent operator to set its argument null automatically. Your C++ is simulating this behavior.

In practice, the value of this discipline is not what you'd hope. Once in a long while it prevents a silly error. One nice thing, however, is that debugger displays of pointer content make sense.

Is it safe to delete a NULL pointer?

delete performs the check anyway, so checking it on your side adds overhead and looks uglier. A very good practice is setting the pointer to NULL after delete (helps avoiding double deletion and other similar memory corruption problems).

I'd also love if delete by default was setting the parameter to NULL like in

#define my_delete(x) {delete x; x = NULL;}

(I know about R and L values, but wouldn't it be nice?)



Related Topics



Leave a reply



Submit