¿Es seguro eliminar un puntero NULL?

¿Es seguro eliminar un puntero NULL?

¿Y es un buen estilo de encoding?

delete realiza el control de todos modos, por lo que revisarlo de lado agrega sobrecarga y se ve más feo. Una muy buena práctica es establecer el puntero a NULL después de delete (ayuda a evitar el doble borrado y otros problemas similares de corrupción de memoria).

También me encantaría si delete de manera predeterminada estuviera configurando el parámetro a NULL como en

 #define my_delete(x) {delete x; x = NULL;} 

(Sé acerca de los valores R y L, pero ¿no sería agradable?)

Del borrador C ++ 0x estándar.

$ 5.3.5 / 2 – “[…] En cualquiera de las alternativas, el valor del operando de eliminación puede ser un valor de puntero nulo. [… ‘”

Por supuesto, nadie haría ‘eliminar’ un puntero con valor NULL, 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. Como la eliminación de un valor de puntero NULL es segura, se puede escribir realmente la lógica de eliminación sin comprobaciones explícitas para eliminar el operando NULL.

Como un aparte, C Standard $ 7.20.3.2 también dice que ‘free’ en un puntero NULL no hace ninguna acción.

La función gratuita hace que el espacio apuntado por ptr sea desasignado, es decir, que esté disponible para una asignación posterior. Si ptr es un puntero nulo, no se produce ninguna acción.

Sí, es seguro.

No hay daño al eliminar un puntero nulo; a menudo reduce el número de pruebas al final de una función si los punteros no asignados se inicializan a cero y luego simplemente se eliminan.


Como la oración anterior ha causado confusión, un ejemplo, que no es una excepción, es seguro 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 liendres que se pueden elegir con el código de muestra, pero el concepto es (espero) claro. Las variables del puntero se inicializan a cero para que las operaciones de delete al final de la función no necesiten probar si no son nulas en el código fuente; el código de la biblioteca realiza esa comprobación de todos modos.

Eliminar un puntero nulo no tiene ningún efecto. No es un buen estilo de encoding necesariamente porque no es necesario, pero tampoco está mal.

Si está buscando buenas prácticas de encoding, considere usar punteros inteligentes en su lugar, por lo que no necesita delete en absoluto.

Para complementar la respuesta de ruslik, en C ++ 14 puedes usar esa construcción:

 delete std::exchange(heapObject, nullptr); 

Es seguro a menos que haya sobrecargado el operador de eliminación. si sobrecargó el operador de eliminación y no maneja la condición nula, entonces no es seguro en absoluto.

He experimentado que no es seguro (VS2010) eliminar [] NULL (es decir, syntax de matriz). No estoy seguro de si esto es de acuerdo con el estándar de C ++.

Es seguro eliminar NULL (syntax escalar).