Siempre me pregunté por qué la configuración automática del puntero a NULL después de la eliminación no es parte del estándar. Si esto se soluciona, muchos de los bloqueos debidos a un puntero no válido no ocurrirían. Pero habiendo dicho eso, puedo pensar en un par de razones por las cuales el estándar habría restringido esto:
Actuación:
Una instrucción adicional podría ralentizar el
delete
rendimiento.Podría ser por
const
punteros.Entonces, de nuevo, el estándar podría haber hecho algo para este caso especial, supongo.
¿Alguien sabe las razones exactas para no permitir esto?
Primero, establecer en nulo requeriría una variable almacenada en la memoria. Es cierto que generalmente tiene un puntero en una variable, pero a veces es posible que desee eliminar un objeto en una dirección calculada. Eso sería imposible con la eliminación "nula".
Luego viene el rendimiento. Es posible que haya escrito código de tal manera que el puntero se salga del alcance inmediatamente después de que se elimine . Llenarlo con nulo es solo una pérdida de tiempo. Y C ++ es un lenguaje con la ideología "¿no lo necesita? Entonces no tiene que pagarlo".
Si necesita seguridad, hay una amplia gama de punteros inteligentes a su servicio o puede escribir los suyos, mejores y más inteligentes.
fuente
delete (ptr + i)
Puede tener múltiples punteros apuntando a esa memoria. Crearía una falsa sensación de seguridad si el puntero que especificó para la eliminación se estableció en nulo, pero no todos los demás punteros. Un puntero no es más que una dirección, un número. También podría ser un int con una operación de desreferenciación. Mi punto es que también tendría que escanear cada puntero para encontrar aquellos que hacen referencia a la misma memoria que acaba de eliminar, y anularlos también. Sería computacionalmente intenso escanear todos los punteros para esa dirección y anularlos, porque el lenguaje no está diseñado para eso. (Aunque algunos otros idiomas estructuran sus referencias para lograr un objetivo similar de una manera diferente).
fuente
Un puntero se puede guardar en más de una variable, establecer uno de estos en NULL aún dejaría punteros inválidos en las otras variables. Entonces, en realidad no ganas mucho, es más probable que estés creando una falsa sensación de seguridad.
Además de eso, puedes crear tu propia función que haga lo que quieras:
fuente
Porque no hay realmente ninguna necesidad de hacerlo, y porque requeriría eliminar tomar puntero a puntero en lugar de solo puntero.
fuente
delete
se usa principalmente en destructores, en cuyo caso establecer un miembro en NULL no tiene sentido. Unas líneas más tarde, al cierre}
, el miembro ya no existe. En los operadores de asignación, una eliminación suele ir seguida de una asignación de todos modos.Además, haría que el siguiente código sea ilegal:
fuente
Aquí hay otra razón; supongamos que delete establece su argumento en NULL:
¿Debe la barra establecerse en NULL? ¿Puedes generalizar esto?
fuente
Si tiene una matriz de punteros y su segunda acción es eliminar la matriz vacía, entonces no tiene sentido establecer cada valor como nulo cuando la memoria está a punto de liberarse. Si quieres que sea nulo ... escríbelo :)
fuente
C ++ le permite definir su propio operador nuevo y eliminar para que, por ejemplo, usen su propio asignador de grupo. Si hace esto, entonces es posible usar new y delete con cosas que no son estrictamente direcciones pero dicen índices en la matriz de su grupo. En este contexto, el valor de NULL (0) podría tener un significado legal (que se refiere al primer elemento del grupo).
Por lo tanto, tener Delete set NULL automáticamente en su argumento no siempre tiene el significado de: establecer el valor en un valor no válido. El valor no válido no siempre puede ser NULL.
fuente
La filosofía de C ++ es "paga solo si la usas". Creo que puede responder a tu pregunta.
Además, a veces puede tener su propio montón que recuperará la memoria eliminada ... o, a veces, el puntero no es propiedad de ninguna variable. O puntero almacenado en pocas variables: es posible que cero solo una de ellas.
Como puede ver, tiene muchos problemas y posibles problemas.
fuente
Establecer el puntero en NULL automáticamente no resolvería la mayoría de los problemas con un mal uso del puntero. El único bloqueo que evitaría es si intenta eliminarlo dos veces. ¿Qué sucede si llama a una función miembro en dicho puntero? Todavía se bloquearía (suponiendo que acceda a las variables miembro). C ++ no le impide llamar a ninguna función en punteros NULL, ni debería hacerlo desde el punto de vista del rendimiento.
fuente
Veo personas que dan respuestas extrañas a esta pregunta.
ptr = NULL; ¿Cómo puede una declaración tan simple causar un retraso en el rendimiento?
Otra respuesta es decir que podemos tener múltiples punteros apuntando a la misma ubicación de memoria. Seguramente podemos. En este caso, la operación de eliminación en un puntero haría que ese puntero sea NULL (si eliminar hace que el puntero sea NULL) y el otro puntero no sea NULL y apunte a la ubicación de memoria que está libre.
La solución para esto debería haber sido que el usuario debería eliminar todos los punteros que apuntan a la misma ubicación. Internamente debe verificar si la memoria ya está liberada que no liberar. Solo haga que el puntero sea NULL.
Stroustrup podría haber diseñado eliminar para trabajar de esta manera. Pensó que los programadores se encargarían de esto. Entonces lo ignoró.
fuente