2010-08-15 13 views
5

Tengo una pregunta sobre la desasignación de memoria y las excepciones. cuando uso delete para eliminar un objeto creado en el montón. Si se produce una excepción antes de esta eliminación, ¿se va a filtrar la memoria o se va a ejecutar esta eliminación?Desasignación de memoria y excepciones

+0

¿Quiere decir antes, no durante? Bueno, entonces esto es obvio que si no se llamará a 'delete' (porque se lanza una excepción antes), entonces no se libera ninguna memoria. Si solicita una excepción durante la destrucción, http://www.parashift.com/c++faq-lite/exceptions.html#faq-17.3 – adf88

Respuesta

3

Esto depende de dónde esté ese delete. Si está dentro del catch que capta la excepción, podría invocar.

try { 
    f(); // throws 
} catch(...) { 
    delete p; // will delete 
} 

Si es después de la catch que detecta la excepción y que catch no vuelve de la función (es decir, permite el flujo de ejecución para proceder después del bloque de catch), entonces el delete podría llamarse.

try { 
    f(); // throws 
} catch(...) { 
    // execution proceeds beyond catch 
} 
delete p; // will delete 

Si el delete no se encuentra en un bloque de catch o después de un bloque de catch que permite la ejecución de proceder entonces el delete no va a llamar.

try { 
    f(); // throws 
    delete p; // will not delete 
} // ... 

Como se puede imaginar, en los dos primeros casos anteriores, el delete no sean invocados si hay un tiro antes de la delete:

try { 
    f(); // throws 
} catch(...) { 
    g(); // throws 
    delete p; // will not delete 
} 
+1

Tenga en cuenta que las excepciones son buenas porque no tiene que atraparlas en cada una de ellas. función en la pila de llamadas. Se pueden comprar en un nivel "externo". ¿Cómo se libera la memoria asignada dentro de las funciones internas? Como por ejemplo si la función f() arroja una memoria asignada de excepción. ¿Sería una buena idea atrapar la excepción dentro de f() y liberar memoria y luego volver a lanzarla al siguiente nivel en la pila de llamadas? – NickSoft

5

En el caso que describa, la memoria va a tener fugas.

Dos trucos para evitar este problema:

  • uso de punteros inteligentes, que no sufren el mismo problema (solución preferida)
    -> el puntero inteligente en construido en la pila, su por lo tanto, el destructor se llama, no importa qué, y la eliminación del contenido en punta se proporciona en el destructor

  • declaraciones utilización try/catch, y eliminar el elemento en la declaración de capturas, así

0

También hay que asegurarse de que "excepción" realmente significa excepción C++ que puede ser atrapada por try/catch. También existen otras excepciones en el sistema que C++ try/catch no puede detectar (por ejemplo, división por 0).

En tales casos (más allá del alcance de los estándares de C++), también, "eliminar" no se ejecutará a menos que estas excepciones sean detectadas y el manejador invoca explícitamente "eliminar" apropiadamente.

Cuestiones relacionadas