Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

In the C++03 Standard, I see:

5.3.5 Delete

2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In either alternative, if the value of the operand of delete is the null pointer the operation has no effect. In the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a sub-object (1.8) representing a base class of such an object (clause 10). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression.72) If not, the behavior is undefined.

In the C++11 Draft Standard (N3337), I see:

5.3.5 Delete

2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined. In the second alternative (delete array), the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression. If not, the behavior is undefined.

I have highlighted the differences between the specifications in the two standards. I find it strange that the 2003 standard was more emphatic on how NULL pointers must be dealt with while the 2011 standard says nothing about what an implementation must do.

  1. Did the verbiage of the C++11 standard change between the draft standard and the actual standard? If so, how?

  2. If the verbiage of the draft standard remains unchanged in the actual standard, what was the rationale for changing a very strong statement to almost nothing between 2003 and 2011?

like image 411
R Sahu Avatar asked Aug 15 '14 15:08

R Sahu


People also ask

Can you call delete on a null pointer?

Explanation: Deleting a null pointer has no effect, so it is not necessary to check for a null pointer before calling delete.

What happens if you call delete on Nullptr?

In c++03 it is pretty clear that deleting a null pointer has no effect. Indeed, it is explicitly stated in §5.3. 5/2 that: In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.

Is it OK to delete Nullptr?

Simple answer is YES. It is perfectly safe to delete a null pointer. In C++ delete operator is used to deallocate the memory block pointed by the pointer by releasing the memory allocated via new operator.

Is it fine to call delete twice for a pointer?

It is undefined behavior to call delete twice on a pointer. Anything can happen, the program may crash or produce nothing.


2 Answers

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.

like image 187
Shafik Yaghmour Avatar answered Oct 16 '22 23:10

Shafik Yaghmour


The latest C++14 draft (N3797) has roughly equivalent wording in this section. But the behaviour is equally-strongly specified, just not in quite the same paragraph.

If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2 ).

If the value of the operand of the delete-expression is not a null pointer value, then: — If the allocation call for the new-expression for the object to be deleted was not omitted ( 5.3.4 ), the delete-expression shall call a deallocation function ( 3.7.4.2 ). The value returned from the allocation call of the new-expression shall be passed as the first argument to the deallocation function. — Otherwise, the delete-expression will not call a deallocation function ( 3.7.4.2 ).

These paragraphs are clearly just as strong as C++03. The Committee could not have broken the behaviour of programs which delete null pointers, as these are widespread and the cost of fixing would be much too large. It would have made C++11 unimplementable.

like image 21
Puppy Avatar answered Oct 16 '22 21:10

Puppy