Calling Delete on Null Pointers - C++03 VS C++11

Calling delete on NULL pointers - C++03 vs C++11

It looks like we can find a rationale for this change in defect report 348, which says:

Specifically, standard says in 5.3.5 [expr.delete] paragraph 2:

...if the value of the operand of delete is the null pointer the operation has no effect.


Standard doesn't specify term "has no effect". It is not clear from
this context, whether the called deallocation function is required to
have no effect, or delete-expression shall not call the deallocation
function.

Furthermore, in para 4 standard says on default deallocation function:

If the delete-expression calls the implementation deallocation
function (3.7.4.2 [basic.stc.dynamic.deallocation]), if the operand of
the delete expression is not the null pointer constant, ...


Why it is so specific on interaction of default deallocation function and delete-expr?

If "has no effect" is a requirement to the deallocation function, then
it should be stated in 3.7.4.2 [basic.stc.dynamic.deallocation], or in
18.6.1.1 [new.delete.single] and 18.6.1.2 [new.delete.array], and it should be stated explicitly.

part of the resolution was the change in wording that you noted, although the language around that phrasing has changed quite a bit but the logic of getting rid of the has no effect language still stands, it is not a well defined term and so should be replaced with well specified language.

Calling delete or delete[] on NULL pointer

Yes, the standard, since C++98, guarantees that delete or delete[] on a nullpointer has no effect.

C++98 §5.3.5/2

In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.

This was so also before the first standard, when the language was defined by the Annotated Reference Manual.


Regarding

version compiled for Linux with g++ (unfortunately, I do not remember the g++ version) was throwing NULL pointer reference

That's impossible to discuss without a concrete and preferably complete example that reproduces the behavior. It had nothing to do with deleting a nullpointer.

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?)

What C++17 standard say about calling delete on nullptr?

Yes it is valid, and it results in a noop. reference

If expression evaluates to a null pointer value, no destructors are called, and the deallocation function is not called.

Is it still safe to delete nullptr in c++0x?

5.3.5/7 says:

If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will call a deallocation function (3.7.4.2). Otherwise, it is unspecified whether the deallocation function will be called.

And 3.7.4.2/3 says:

The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect.

So the behavior is well defined, as long as the standard deallocation function is used, or a user-provided deallocation function handles null pointers correctly.

Is there any reason to check for a NULL pointer before deleting?

It's perfectly "safe" to delete a null pointer; it effectively amounts to a no-op.

The reason you might want to check for null before you delete is that trying to delete a null pointer could indicate a bug in your program.

Edit

NOTE: if you overload the delete operator, it may no longer be "safe" to delete NULL

Deleting NULL pointer memory

Yes, you got memory leaks here. Memory leaks are common problems, but they won't cause your program to be killed immediately, sometimes when the system memory is running out, the OS will kill other programs that are not leaking, they are victims.

Delete a NULL pointer is always safe, and it's duplicated. What you have learned is wrong. And you may also view the doc from cpp reference.

For modern c++, it's always recommended to use smart pointers, we don't delete pointers by hand anymore, most leaks are avoided.

Deleting a null pointer

delete will check if the pointer is NULL for you, so you're right that the check isn't needed.

You might also see that some people set the pointer to NULL after it's deleted so that you don't do anything stupid like try and use memory that is no longer yours or stop you from deleting the pointer twice, which will cause an error.

Legality of using delete-expression on a pointer not obtained from usual new

delete new (operator new(1)) char; does appear to be legal. Like you said, the standard does not make any exceptions for placement new.

Your second example is also legal:

void* p = operator new(1);
new (p) char;
delete static_cast<char*>(p);

Let's walk through what happens step by step. The call to operator new implicitly creates a char object and returns a pointer to said object1. So p starts out already pointing to a char object. The placement new expression constructs a new char object over the old one, ending the lifetime of the old object; according to the rules of the abstract machine, this magically changes the value of p such that it points to this new object; see [basic.life]/8. Finally, static_cast<char*>(p) returns a pointer pointing to that same char object. That is, this pointer has the same value as the pointer that was returned by the placement new. So if the first example is valid, so is this one.

Note that [expr.delete]/2 does not suggest that in order for an operand to delete to be valid, there must be some sort of valid "chain of custody" from a new expression to the value that is now being deleted. It merely says "... a pointer value that resulted from a previous non-array new-expression..." The value of the pointer is all that matters. In your second example, p has the same value as the pointer returned from the placement new, thanks to [basic.life]/8.

Regarding your third example, delete[] new (operator new(2)) char[2];, I agree that it shouldn't be legal. I suggest filing a defect report.

1 See [intro.object]/13.

Why is deleting null pointer allowed in C++

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?



Related Topics



Leave a reply



Submit