pointer new explained bidimensional array c++ pointers memory-management

new - pointer c++



¿Por qué se invoca "delete operador" cuando llamo "delete" en un puntero nulo? (2)

Al leer las respuestas a esta pregunta , noté que las respuestas ( esto por ejemplo) implican que se puede llamar al operator delete incluso cuando la instrucción delete se ejecuta en un puntero nulo.

Así que escribí un pequeño fragmento:

class Test { public: void* operator new( size_t ) { /*doesn''t matter*/ return 0; } void operator delete( void* ptr ) { ptr; //to suppress warning and have a line to put breakpoint on } }; int main() { Test* ptr = 0; delete ptr; }

y - sorprendentemente para mí - Test::operator delete() se invoca con ptr sosteniendo un puntero nulo.

Según tengo entendido, el operator new asigna memoria y el operator delete devuelve la memoria al asignador. Si llamo a delete statement en un puntero nulo, significa que no había ningún objeto detrás del puntero y que no hay memoria para regresar al asignador.

delete instrucción delete incluye invocar un destructor. Cuando paso un puntero nulo, el destructor seguramente no se invoca; C ++ se ocupa de eso. Entonces, ¿por qué se invoca la operator delete en este caso?


El lenguaje en el próximo estándar C ++ 0x (sección 5.3.5 [expr.delete] ) es el siguiente:

Si el valor del operando de la expresión de eliminación no es un valor de puntero nulo, la expresión de eliminación llamará a una función de desasignación (3.7.4.2). De lo contrario, no se especifica si se llamará a la función de desasignación. [Nota: la función de desasignación se llama independientemente de si el destructor para el objeto o algún elemento de la matriz arroja una excepción. - nota final]

Entonces, es un comportamiento no especificado, algunos compiladores pueden llamar al operator delete cuando se operator delete un puntero NULL y otros no.

EDITAR: El término función de desasignación utilizada por el estándar parece estar causando cierta confusión. Viene con una referencia. Algún lenguaje clave de 3.7.4.2 [basic.stc.dynamic.deallocation] que puede ayudar a aclarar:

Si una clase T tiene una función de desasignación de miembros llamada operator delete con exactamente un parámetro, entonces esa función es una función de desasignación usual (no colocación).

El estándar también es muy claro que la operator delete definida por el usuario necesita aceptar un parámetro que es un valor de puntero nulo:

El valor del primer argumento suministrado a una función de desasignación puede ser un valor de puntero nulo; si es así, y si la función de desasignación se proporciona en la biblioteca estándar, la llamada no tendrá efecto.

Pero debido al comportamiento no especificado 5.3.5, no debe confiar en operator delete se llame a su operator delete cuando el puntero es nulo.


La eliminación del operador es como cualquier otro operador, ¿por qué no se invocaría? No puede examinar sus argumentos antes de ser invocado.

Esto es como preguntar por qué se invoca el operator+ cuando se agrega 0.