cómo hacer que el puntero inteligente quede fuera del alcance al salir ()

Pasé un poco de tiempo escribiendo una aplicación para practicar y me ha gustado usar punteros inteligentes en todo momento para evitar pérdidas de memoria en caso de que olvide borrar algo. Al mismo tiempo, también me ha gustado usar excepciones para informar fallas en un constructor e intentar manejarlo. Sin embargo, cuando no puede, me gustaría que salga del programa en ese lugar a través de una llamada a assert() o exit(). Sin embargo, al usar la biblioteca crtdbg en msvc, informa una pérdida de memoria de los punteros inteligentes que tienen algo asignado dinámicamente. Esto significa una de dos cosas para mí. 1) los punteros inteligentes nunca se salieron del alcance de donde estaban asignados y nunca desasignaron, lo que provocó algunas fugas de memoria, o 2) crtdbg no detecta la desasignación porque no sale en la principal. Desde este sin embargo, usando _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); al comienzo del programa detectará las fugas desde cualquier punto de salida, y sigo recibiendo los errores de fuga de memoria al usar eso.

Entonces, mi pregunta para ustedes, ¿la memoria se desasignará realmente al salir o afirmar, y si no, podría derivar de std::shared_ptr e implementar mi propia solución para catalogar objetos asignados dinámicamente para desasignarlos justo antes de la llamada? para salir o afirmar, o es demasiado trabajo para una solución más simple?

preguntado el 30 de julio de 12 a las 20:07

¿Por qué le importa la desasignación si el proceso muere de todos modos? -

Si llamas exit, la pila no se desenrolla y las variables locales no se destruyen. Sin embargo, no está claro lo que está tratando de lograr: si desea que se destruyan las variables locales, inicie una excepción y catch (...) in main() para asegurarse de que la pila se desenrolle. -

@ yuri kilochek: buena pregunta. ¿importa? Cuando veo los errores de pérdida de memoria, me preocupa, pero si el proceso se cierra, ¿todavía tengo que preocuparme por eso? -

@FatalCatharsis no lo haces. OS libera todos los recursos que el proceso adquirió durante la ejecución. Sin embargo, es posible que desee conservar algún estado externo de todos modos, como volcar un búfer en un archivo antes de la finalización. -

@yuri kilochek: bueno, entonces supongo que esa es la respuesta a mi pregunta, ignórala y desaparecerá :P. Gracias un montón -

2 Respuestas

Cuando el programa sale, el sistema operativo recupera la memoria de todos modos, por lo que si la fuga le preocupa, no debería hacerlo.

Sin embargo, si tiene lógica en sus destructores y los objetos deben destruirse, llamando exit omite explícitamente toda desasignación. Una solución para esto es lanzar una excepción en la que llamarías a exit, atraparla main y volver.

#include "stdlib.h"

void foo()
{
   //exit(0);
   throw killException();
}

int main
{
   try
   {
      foo();
   }
   catch (killException& ex)
   {
      //exit program calling destructors
      return EXIT_FAILURE;
   }
}

Respondido 30 Jul 12, 21:07

la primera oración es todo lo que necesitaba, los errores de fuga de memoria me llevaron a creer que algo estaba terriblemente mal en la forma en que estaba haciendo esto, pero supongo que solo al salir del programa se liberan todos los recursos, así que no importa :\. gracias un montón. Aceptaré cuando pueda - Catarsis fatal

@FatalCatharsis: Algo is mal con la forma en que está haciendo esto, independientemente de si la memoria se filtró o no :) - David Rodríguez - Dribeas

@DavidRodríguez-dribeas: ¿los puntos de salida múltiples son realmente tan malos? Estoy saliendo después de manejar una excepción dentro del constructor, porque si esto falla, entonces no es seguro usar el objeto. Si intenta usar el objeto después de que se lanza una excepción, habrá errores. Preferiría manejar y salir directamente dentro del constructor, luego propagarlo para que lo maneje un usuario externo, porque entonces podrían continuar con el programa y seguir usándolo. ¿Qué más recomendarías en esta situación? - Catarsis fatal

@FatalCatharsis: el constructor debería fallar con una excepción, pero eso no significa que toda la aplicación deba morir. Algún código de nivel superior podría ser capaz de manejar el problema. La lógica de nivel superior debería tener la oportunidad de recuperarse de la condición de error. - David Rodríguez - Dribeas

El verdadero problema no es con la memoria, sino con otros recursos. El sistema operativo (en la mayoría de los casos, a menos que esté ejecutando un sistema integrado) recuperará la memoria del proceso cuando termine, por lo que la memoria no se recuperará. filtrada en el sistema operativo. El problema real podría estar relacionado con otros recursos, externos a su proceso, que podrían necesitar ser liberados antes de que se complete su proceso...

En cualquier caso, ¿por qué prefieres abort or exit en lugar de dejar que la excepción se propague? En general, debe manejar solo las excepciones que desea administrar y dejar que las demás no funcionen. Si bien es posible que no pueda recuperarse de él, la persona que llama podría hacerlo. Al capturar la excepción y salir del programa en el acto, está eliminando la opción de manejo de los usuarios.

Respondido 30 Jul 12, 20:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.