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 ofdelete
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 ofdelete
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.
Did the verbiage of the C++11 standard change between the draft standard and the actual standard? If so, how?
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?
Explanation: Deleting a null pointer has no effect, so it is not necessary to check for a null pointer before calling delete.
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.
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.
It is undefined behavior to call delete twice on a pointer. Anything can happen, the program may crash or produce nothing.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With