45 votos

¿Por qué tengo que eliminar[]?

Digamos que tengo una función como esta:

int main()
{
    char* str = new char[10];

    for(int i=0;i<5;i++)
    {
        //Do stuff with str
    }

    delete[] str;
    return 0;
}
  1. ¿Por qué tengo que borrar str si voy a terminar el programa de todos modos? No me importa si es que la memoria va a una tierra llena de unicornios si voy a salir, ¿verdad?

  2. Es una buena práctica?

  3. ¿Tiene consecuencias más profundas?

77voto

Eric Lippert Puntos 300275

Y si en realidad tu pregunta es realmente "tengo este trivial programa, es ACEPTAR que no me libre de un par de bytes antes de que salga?", la respuesta es que sí, que está bien. En cualquier sistema operativo moderno que va a estar bien. Y el programa es trivial; no es como te vas a poner en un marcapasos o ejecución de los sistemas de frenado de un Toyota Camry con esta cosa. Si el cliente sólo es usted, entonces la única persona en la que usted puede posiblemente impacto por ser descuidado es usted.

El problema viene cuando se empiezan a generalizar para no trivial de los casos a partir de la respuesta a esta pregunta le preguntó acerca de un caso trivial.

Así que vamos lugar dos preguntas acerca de algunos de los casos triviales.

Tengo una larga duración de servicio que asigna y cancela la asignación de memoria en formas complejas, quizá con múltiples asignadores de golpear a varios montones. Cerrando mi servicio en el modo normal es un proceso complicado y largo proceso que implica garantizar que la externa del estado -- archivos, bases de datos, etc. -- son siempre apague. Debería asegurarse de que todos los bytes de la memoria que me asignan es desasignado antes de que se me apague?

Sí, y yo te diré por qué. Una de las peores cosas que le puede pasar a una larga duración de servicio se si de forma accidental fugas de memoria. Incluso pequeñas fugas pueden agregar hasta enormes fugas a lo largo del tiempo. Una técnica estándar para encontrar y corregir las pérdidas de memoria es el instrumento de asignación de los montones de modo que en tiempo de apagado de registrar todos los recursos que fueron asignados sin ser liberado. A menos que te gusta de perseguir a un montón de falsos positivos y pasar un montón de tiempo en el depurador, siempre libre en su memoria , aun cuando ello no sea estrictamente necesario.

El usuario está esperando a que se cierre el servicio puede tardar miles de millones de nanosegundos, así que a quién le importa si usted causa un poco de presión extra virtual en el asignador de asegurarse de que todo está limpito? Esto es sólo el precio que usted paga para las grandes complicado software. Y no es como usted está cerrando el servicio todo el tiempo, así que, de nuevo, a quién le importa si su un par de milisegundos más lento de lo que podría ser?

Tengo la misma de larga duración de servicio. Si detecto que uno de mis estructuras internas de datos está dañado deseo "fail fast". El programa está en un estado indefinido, es probable que se ejecuta con privilegios elevados, y voy a suponer que si puedo detectar el estado corrupto, es porque mi servicio está siendo activamente atacado por hostiles partes. Lo más seguro es cerrar el servicio de inmediato. Creo que sería más bien permitir a los atacantes a denegar el servicio a los clientes que el riesgo de que el servicio de permanecer para arriba y atacar a los usuarios de datos. En esta parada de emergencia del escenario debería asegurarse de que cada byte de memoria asignada es liberado?

Por supuesto que no. El sistema operativo se va a hacer cargo de eso. Si la pila está dañado, los atacantes podrían ser la esperanza de que la memoria libre como parte de su explotar. Cada milisegundo cuenta. Y ¿para qué molestarse en el pulido de los pomos de las puertas y fregar la cocina antes de soltar un tactical nuke en el edificio?

Así que la respuesta a la pregunta "debo liberar memoria antes de que mi programa se cierra?" es: "depende de lo que su programa no".

39voto

75inchpianist Puntos 3154

Sí es una buena práctica. Usted NUNCA debe asumir que su sistema operativo se encargará de su desasignación de memoria, si tienes este hábito, tornillo más adelante.

Para responder a su pregunta, sin embargo, al salir de la principal, el sistema operativo libera toda la memoria que posea en el proceso, de modo que incluye los subprocesos que se pueden haber generado o variables asignadas. El sistema operativo se encargará de liberar la memoria para que otros la utilicen.

24voto

Roddy Puntos 32503

Nota importante : deletes'liberación de memoria es casi sólo un efecto secundario. Lo importante no es destruir el objeto. Con RAII diseños, esto podría significar cualquier cosa, desde el cierre de los archivos, liberando OS maneja, la terminación de los hilos, o la eliminación de archivos temporales.

Algunas de estas acciones sería manejado por el sistema operativo automáticamente cuando el proceso termina, pero no todos.

En tu ejemplo, no hay ninguna razón para que NO llame delete. pero no hay ninguna razón para llamar a new , por lo que se puede eludir el problema de esta manera.

char str[10];

O, puede eludir el eliminar (y la excepción de las cuestiones de seguridad involucradas) por el uso de punteros inteligentes...

Así que, por lo general usted siempre debe asegurarse de que el objeto de la vida es manejado apropiadamente.

Pero no siempre es fácil: Soluciones para la inicialización estática fin de fiasco a menudo significa que no tienes más remedio que confiar en el sistema operativo de limpieza en un puñado de singleton-tipo de objetos para usted.

16voto

Ben Jackson Puntos 28358

Contrario respuesta: No, es una pérdida de tiempo. Un programa con una gran cantidad de datos asignados tendría que tocar casi todas las páginas en orden para devolver todas las asignaciones de la lista libre. Esto desperdicia el tiempo de la CPU, crea la presión de memoria para datos interesantes, y posiblemente incluso hace que el proceso de intercambio de páginas de vuelta de disco. Simplemente salir libera toda la memoria del sistema operativo, sin ninguna otra acción.

(no es que yo no estoy de acuerdo con las razones en que "Sí", simplemente creo que hay argumentos en ambos sentidos)

6voto

eandersson Puntos 8571

Su Sistema Operativo debe encargarse de la memoria y limpiar cuando sale de su programa, pero en general es una buena práctica para liberar la memoria que ha reservado. Creo, personalmente, lo mejor es entrar en la mentalidad correcta de hacerlo, ya que mientras que usted está haciendo programas sencillos, que tienen más probabilidades de hacerlo para aprender.

De cualquier manera, la única manera de garantizar que la memoria se libera es haciéndolo uno mismo.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X