Why is deleting null pointer allowed in C++
Asked Answered
C

7

8

I remember reading somewhere that it's neccessary for delete NULL to be a valid operation in C++, but I can't remeber the reason why it should be so. Would someone please remind me?

Clydeclydebank answered 22/9, 2012 at 6:22 Comment(1)
Another way to look at it is to reverse the question; you can guarantee that NULL never points to anything, therefore would you prefer it if delete NULL threw an exception? - or even worse, if it were left undefined by the standard and open to inconsistent behaviour between different compilers?Listing
L
11

The rule is not strictly necessary in that the language could exist without it; it is simply a decision made by the standards committee. The null pointer is not a valid memory address. However, I would like to believe that each decision is made for a reason, and those reasons are worth knowing.

This rule simplifies the management of failure cases and other instances in which a pointer may be null. It is an easy, inexpensive check to make, and it adds appreciable convenience to the language.

For example, if many conditions exist which would result in dynamic memory allocation, but others also exist which will not, it's convenient to be able to just stick a delete at the end and not worry about it.

// contrived example
void foo(int n) {
    char *p = nullptr;
    switch(n) {
        case whatever:
        case something_else:
            p = new char[n];
            break;
    }

    // some code...

    delete [] p;  // look Ma, no check!
}

If delete nullptr were illegal then every call to delete would be surrounded by...

if(ptr)

...and that would be lame. Since this would be the norm, an essentially mandatory convention, why not just eliminate the need to check entirely? Why require an extra 5 characters (minimum) for every call to delete?

Legation answered 22/9, 2012 at 6:25 Comment(7)
@LuchianGrigore: It is possible that I have had at least seven glasses of wine on this wonderful Friday evening... I wrote delete n didn't I? :DLegation
aren't there platforms on which 0 is a valid memory address?Simmons
@stijn: 0 is defined to never be a valid address, so no.Legation
only for c++ then? I'm pretty sure I've seen dsp platforms where internal memory starts at 0, but that was in C. Or maybe they just are non-compliant.Simmons
@stijn: The C and C++ languages guarantee that 0 is never a valid memory address. How a given compiler implements that for a given platform is, well, implementation defined. Most operating systems ensure that 0 is never returned as a valid memory address to a program (doesn't mean they all do though).Legation
@stijn: I need to correct myself; a null pointer must always be invalid. The null pointer does not necessarily have to be 0. NULL is a macro which is defined to be 0 in C. The language itself speaks in terms of the null pointer and its semantics. In practice, they are usually one in the same, but they need not be. I had to check the standard :DLegation
In Linux it was possible to make 0 a valid memory address, but it is disabled by default for security reasons. But it is still useful and used by Wine when running MS-DOS programs.Gauhati
H
13

Exact Reason:

  • Because C++ Standard committee decided so.

Possible Reasoning:

  • Because it would be too much code bloat to check every pointer for NULL before calling delete in user code.
Hereabout answered 22/9, 2012 at 6:24 Comment(0)
L
11

The rule is not strictly necessary in that the language could exist without it; it is simply a decision made by the standards committee. The null pointer is not a valid memory address. However, I would like to believe that each decision is made for a reason, and those reasons are worth knowing.

This rule simplifies the management of failure cases and other instances in which a pointer may be null. It is an easy, inexpensive check to make, and it adds appreciable convenience to the language.

For example, if many conditions exist which would result in dynamic memory allocation, but others also exist which will not, it's convenient to be able to just stick a delete at the end and not worry about it.

// contrived example
void foo(int n) {
    char *p = nullptr;
    switch(n) {
        case whatever:
        case something_else:
            p = new char[n];
            break;
    }

    // some code...

    delete [] p;  // look Ma, no check!
}

If delete nullptr were illegal then every call to delete would be surrounded by...

if(ptr)

...and that would be lame. Since this would be the norm, an essentially mandatory convention, why not just eliminate the need to check entirely? Why require an extra 5 characters (minimum) for every call to delete?

Legation answered 22/9, 2012 at 6:25 Comment(7)
@LuchianGrigore: It is possible that I have had at least seven glasses of wine on this wonderful Friday evening... I wrote delete n didn't I? :DLegation
aren't there platforms on which 0 is a valid memory address?Simmons
@stijn: 0 is defined to never be a valid address, so no.Legation
only for c++ then? I'm pretty sure I've seen dsp platforms where internal memory starts at 0, but that was in C. Or maybe they just are non-compliant.Simmons
@stijn: The C and C++ languages guarantee that 0 is never a valid memory address. How a given compiler implements that for a given platform is, well, implementation defined. Most operating systems ensure that 0 is never returned as a valid memory address to a program (doesn't mean they all do though).Legation
@stijn: I need to correct myself; a null pointer must always be invalid. The null pointer does not necessarily have to be 0. NULL is a macro which is defined to be 0 in C. The language itself speaks in terms of the null pointer and its semantics. In practice, they are usually one in the same, but they need not be. I had to check the standard :DLegation
In Linux it was possible to make 0 a valid memory address, but it is disabled by default for security reasons. But it is still useful and used by Wine when running MS-DOS programs.Gauhati
T
3

First off, NULL is never a valid pointer value (in a hosted C++ program), and so there's no ambiguity as to whether the pointer points to a live object or not. Second, the internal memory management logic must do its own checking anyway to do the bookkeeping, so presumably nothing would be gained from mandating that the pointer be non-null.

So now we know that there's nothing speaking against this rule, here's the big argument in its favour: It makes it much easier to write code. Consider this simple exception-handling piece of allocation code:

T * p1 = NULL;
T * p2 = NULL;
T * p3 = NULL;

try
{
    p1 = new T;
    p2 = new T;
    p3 = new T;
}
catch (...)
{
    delete p1;
    delete p2;
    delete p3;

    throw;
}

This is simple and uncluttered. If we needed to add NULL-checks everywhere, it would make the code a lot less readable and obscure the code's logic.

Tray answered 22/9, 2012 at 8:7 Comment(0)
B
2

Because the Standard committee know that no program can have NULL to point to a valid object, i.e NULL cannot point to a valid memory so it is safe to write delete NULL , precisly because it doesn't actually delete anything. Since that is safe, then it saves you from the need to check for NULL , before delete:

//if (ptr != NULL) NOT NEEDED
   delete ptr; //safe even if ptr == NULL
Barrow answered 22/9, 2012 at 6:30 Comment(0)
R
2

Because the library implementer just has to write if (ptr == nullptr) return; once. You, the user, would have to write it 9999999999 times throughout your program. Thus, it's a simple case that doing it inside delete is much simpler.

Radiotelegraphy answered 22/9, 2012 at 8:9 Comment(0)
R
1

Deleting a null pointer has no effect (if the deallocation function is one supplied in the standard library[2]), so it is not necessary to check for a null pointer before calling delete.

also check Is it safe to delete a NULL pointer? it may help you

Registered answered 22/9, 2012 at 6:24 Comment(0)
T
0

Well, I do remember clearly that the rules for deleting pointer-to-const (now OK) changed with the standardization, i.e. they were different in the ARM, the Annotated Reference Manual.

But I'm not sure about deleting 0; I think it's always been supported.

Anyway, it's just about convenience, for an operation where the cost of checking is insignificant, and where it can possibly/likely be done more efficiently by the compiler than by some user defined wrapper function for deletion.

Taphole answered 22/9, 2012 at 7:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.