c++ - que - ¿Es seguro eliminar un puntero NULO?
punteros void lenguaje c (7)
Desde el proyecto de norma C ++ 0x.
$ 5.3.5 / 2 - "[...] En cualquiera de las dos alternativas, el valor del operando de eliminación puede ser un valor de puntero nulo. [... ''"
Por supuesto, nadie haría ''borrar'' un puntero con un valor NULO, pero es seguro hacerlo. Idealmente, uno no debería tener código que elimine un puntero NULL. Pero a veces es útil cuando la eliminación de punteros (por ejemplo, en un contenedor) ocurre en un bucle. Dado que la eliminación de un valor de puntero NULL es segura, uno realmente puede escribir la lógica de eliminación sin comprobaciones explícitas para que el operando NULL se elimine.
Además, C Standard $ 7.20.3.2 también dice que ''gratis'' en un puntero NULO no realiza ninguna acción.
La función libre hace que el espacio al que apunta ptr se desasigne, es decir, que esté disponible para una asignación adicional. Si ptr es un puntero nulo, no se produce ninguna acción.
¿Es seguro eliminar un puntero NULO?
¿Y es un buen estilo de codificación?
Eliminar un puntero nulo no tiene efecto. No es un buen estilo de codificación necesariamente porque no es necesario, pero tampoco es malo.
Si está buscando buenas prácticas de codificación, considere utilizar punteros inteligentes, por lo que no necesita delete
en absoluto.
Es seguro a menos que haya sobrecargado el operador de eliminación. Si sobrecargó al operador de eliminación y no está manejando la condición nula, entonces no es seguro en absoluto.
He comprobado que no es seguro (VS2010) eliminar [] NULL (es decir, sintaxis de matriz). No estoy seguro de si esto está de acuerdo con el estándar de C ++.
Es seguro eliminar NULL (sintaxis escalar).
Para complementar la respuesta de ruslik, en C ++ 14 puedes usar esa construcción:
delete std::exchange(heapObject, nullptr);
Sí, es seguro.
No hay daño en borrar un puntero nulo; a menudo reduce el número de pruebas en la cola de una función si los punteros no asignados se inicializan a cero y luego simplemente se eliminan.
Dado que la oración anterior ha causado confusión, un ejemplo, que no es una excepción segura, de lo que se describe:
void somefunc(void)
{
SomeType *pst = 0;
AnotherType *pat = 0;
…
pst = new SomeType;
…
if (…)
{
pat = new AnotherType[10];
…
}
if (…)
{
…code using pat sometimes…
}
delete[] pat;
delete pst;
}
Hay todo tipo de nits que se pueden seleccionar con el código de ejemplo, pero el concepto es (espero) claro. Las variables de puntero se inicializan a cero para que las operaciones de delete
al final de la función no tengan que probar si no son nulas en el código fuente; El código de la biblioteca realiza esa comprobación de todos modos.
delete
realiza la verificación de todos modos, por lo que verificarlo de tu lado agrega sobrecarga y se ve más feo. Una muy buena práctica es configurar el puntero a NULL después de delete
(ayuda a evitar la eliminación doble y otros problemas de corrupción de memoria similares).
También me encantaría que delete
de forma predeterminada estableciera el parámetro en NULL como en
#define my_delete(x) {delete x; x = NULL;}
(Sé acerca de los valores de R y L, pero ¿no sería bueno?)