que punteros puntero matrices informatica ejemplo declaracion aritmetica apuntadores c++ undefined-behavior void-pointers language-lawyer null-pointer

c++ - informatica - punteros y matrices en c



¿Es un comportamiento indefinido eliminar un puntero nulo*nulo? (3)

§5.3.5 / 3 dice,

En la primera alternativa (eliminar objeto), si el tipo estático del operando es diferente de su tipo dinámico, el tipo estático será una clase base del tipo dinámico del operando y el tipo estático tendrá un destructor virtual o el comportamiento es indefinido . En la segunda alternativa (eliminar matriz) si el tipo dinámico del objeto a eliminar difiere de su tipo estático, el comportamiento no está definido.

En la nota a pie de página dice:

73 - Esto implica que un objeto no se puede eliminar utilizando un puntero de tipo void * porque no hay objetos de tipo void.

Así que sí, es UB.

Ahora, una vez que ingresa a la ciudad de comportamiento indefinido, no importa si es nula o no, ya que su comportamiento no puede permanecer bien definido precisamente por la razón de que ya tenía una residencia en la ciudad de comportamiento indefinido.

EDITAR:

Consiguió otro tema que también cita lo mismo y dice su UB:

¿Es seguro eliminar un puntero nulo?

Sé que delete un puntero nulo es un no-op:

En cualquiera de las dos alternativas, si el valor del operando de eliminación es el puntero nulo, la operación no tiene efecto.
(C ++ Standard 5.3.5 [expr.delete] p2 )

Y también que eliminar un puntero void* es un comportamiento indefinido porque no se puede llamar al destructor ya que no hay objetos de tipo void :

En la primera alternativa ( delete object ), el valor del operando de eliminar será un puntero a un objeto que no sea una matriz o un puntero a un subobjeto que representa una clase base de dicho objeto. Si no, el comportamiento es indefinido.
(C ++ Standard 5.3.5 [expr.delete] p2 )

Ahora, normalmente supongo que las cosas que se enumeran primero anulan las que se enumeran más adelante, pero ¿qué pasa con el puntero nulo void* como el siguiente?

void* p = 0; delete p; // UB or well-defined?


Creo que es un comportamiento indefinido. new void no está permitido (no está permitido crear objetos de tipo void ), por lo que llamar a delete en un void* tampoco debería tener sentido. No importa si está apuntando a NULL o no. Nunca usaría tal cosa en mi código.


Me pregunto cómo puede alcanzar una situación en la que está eliminando un puntero solo si es nulo. Pero manteniéndose en el modo de lenguaje legal ...

En C ++ 03

5.3.5 / 1

el operando de eliminar tendrá un tipo de puntero o un tipo de clase que tenga una única conversión a un tipo de puntero.

void * es un tipo de puntero, por lo que un puntero nulo nulo cumple el requisito estático.

5.3.5 / 2

En cualquiera de las alternativas [ delete y delete[] ], si el valor del operando de eliminar es el puntero nulo, la operación no tiene efecto.

Y esto da el comportamiento deseado.

5.3.5 / 3

En la primera alternativa (eliminar objeto), si el tipo estático del operando es diferente de su tipo dinámico, el tipo estático será una clase base del tipo dinámico del operando y el tipo estático tendrá un destructor virtual o el comportamiento es indefinido .

Esto no es relevante, un puntero nulo no hace referencia a un objeto en el que se verifica la restricción adicional.

En C ++ 0X

5.3.5 / 1

El operando tendrá un puntero al tipo de objeto, o un tipo de clase que tenga una única función de conversión no explícita (12.3.2) a un puntero al tipo de objeto.

void * no es un puntero al tipo de objeto, por lo que debe rechazarse.