I know that delete
ing a null pointer is a no-op:
In either alternative, if the value of the operand of delete is the null pointer the operation has no effect.
(C++ Standard5.3.5 [expr.delete] p2
)
And also that deleting a void*
pointer is undefined behaviour because the destructor can't be called as there are no objects of type void
:
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 representing a base class of such an object. If not, the behavior is undefined.
(C++ Standard5.3.5 [expr.delete] p2
)
Now, normally I take it that things that are listed first overrule things that are listed later on, but what about null void*
pointer as the following?
void* p = 0; delete p; // UB or well-defined?
It is also called general purpose pointer. It is not safe to delete a void pointer in C/C++ because delete needs to call the destructor of whatever object it's destroying, and it is impossible to do that if it doesn't know the type.
Explanation: Deleting a null pointer has no effect, so it is not necessary to check for a null pointer before calling delete.
A void pointer, ( void * ) is a raw pointer to some memory location. A null pointer is a special pointer that doesn't point to anything, by definition. It can be a pointer to any type, void or otherwise.
A void pointer can be a null pointer. Thus, a void pointer refers to the type of the pointer, whereas a null pointer refers to the value (address) of the pointer.
I wonder how you can reach up a situation where you are deleting a pointer only if it is null. But staying in language lawyering mode...
5.3.5/1
the operand of delete shall have a pointer type or a class type having a single conversion to a pointer type.
void* is a pointer type so a null void pointer meets the static requirement.
5.3.5/2
In either alternative [
delete
anddelete[]
], if the value of the operand of delete is the null pointer the operation has no effect.
And this gives the wanted behavior.
5.3.5/3
In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined.
This is not relevant, a null pointer doesn't reference an object on which to check the additional constraint.
5.3.5/1
The operand shall have a pointer to object type, or a class type having a single non-explicit conversion function (12.3.2) to a pointer to object type.
void* isn't a pointer to object type, so should be rejected.
§5.3.5/3 says,
In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined73
In the footnote it says,
73 - This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void.
So yeah, its UB.
Now once it enters into the city of undefined behaviour, it doesn't matter whether its null or not, since its behaviour cannot remain well-defined precisely for the reason that it already got a residence in the city of undefined behavior.
EDIT:
Got another topic which also quotes the same and says its UB:
Is it safe to delete a void pointer?
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