[C con Clase] [C con clase] ¿exit() libera memoria dinámica?

David Inocente Romero Escalona di.romero en hotmail.es
Jue Jul 30 22:29:40 CEST 2009


En primer lugar, muchas gracias por tu completa respuesta, Steven. Creo que ya sé por qué he vuelto a esta lista de correo...

 

En mi aplicación, las reservas de memoria de forma dinámica  se realizan en una sola clase C++ (que modeliza una lista de números reales dinámica, es decir, que puede crecer en tiempo de ejecución). Esta clase define adecuadamente su método destructor para que libere toda la memoria que haya podido reservar dinámicamente. Igualmente, todos los métodos de la clase tienen especial cuidado en no dejar zonas de memoria reservadas dinámicamente sin liberar.

 

En ningún otro punto de la aplicación se realiza reserva dinámica de memoria alguna. Todos mis objetos 3D (que son objetos de clases C++) que necesitan usar una lista dinámica de números reales tienen un objeto miembro de la clase mencionada que maneja la memoria dinámica.

 

Además, todos los objetos que creo los creo usando memoria estática (es decir, sin reservar memoria en tiempo de ejecución); de esta forma:

 

Objeto3D objeto3D(<parámetros necesarios>);

 

Por lo tanto, según lo último que comentas, no debo destruir objeto alguno (aunque ese objeto contenga un objeto que a su vez ha reservado memoria dinámicamente). Al terminar el proceso, se destruirán todos los objetos creados (por lo que se llamará a sus destructores y, éstos, acabarán liberando la memoria reservada en tiempo de ejecución).

 

¿estoy en lo correcto?

 

Por cierto, ¿quién envía el mensaje destructor a todos los objetos que se hayan creado al terminar el proceso? ¿el compilador de C++ introduce código objeto que se encarga de realizarlo?

 

Muchas gracias.

 
> Date: Thu, 30 Jul 2009 15:26:51 -0400
> From: srd4121 en njit.edu
> To: cconclase en listas.conclase.net
> Subject: Re: [C con Clase] [C con clase] ¿exit() libera memoria dinámica?
> 
> Hola David,
> 
> David Inocente Romero Escalona wrote:
> > Utilizo el operador predefinido "new" de C++.
> > 
> > Pero mi objetivo al usar la función "exit()" no es liberar memoria,
> > sino terminar el programa.
> > 
> > En concreto, se trata de una aplicación gráfica OpenGL que utiliza el
> > toolkit GLUT. Con dicho toolkit, el programa nunca termina (pues hay
> > un bucle principal infinito que se encarga de ir capturando y
> > manejando diversos eventos). Entonces, para poder finalizar el
> > programa, no queda más remedio que usar la función "exit()" para
> > matar al proceso. En dicha aplicación creo objetos 3D que pertenecen
> > a clases C++ que reservar memoria dinámicamente cuando crean el
> > objeto (para almacenar los vértices y los vectores normales del
> > objeto OpenGL). Esas clases tiene el destructor definido e
> > implementado correctamente para liberar la memoria dinámica que se
> > haya podido reservar. Sin embargo, nunca elimino dichos objetos
> > porque siempre tienen que estar vivos mientras la aplicación se está
> > ejecutando. Mi pregunta viene de aquí. ¿al llamar a la función
> > "exit()" se liberará esa memoria reservada dinámicamente (aunque no
> > haya eliminado explícitamente a dicho objetos)?
> > 
> 
> Si has instanciado esos objetos dinámicamente, entonces debes liberar la 
> memoria dinámica explícitamente. Por ejemplo,
> 
> int main()
> {
> ListaObjetos3D *pLista;
> ...
> pLista = new ListaOjbetos3D;
> ...
> glutMainLoop();
> 
> return 0; // Nunca llegaremos
> }
> 
> Esto es un grave problema, porque no se liberará la memoria que creaste 
> para el objeto. Ciertamente, los sistemas operativos modernos y en 
> particular los que sean multitareas y multi-procesos eliminan toda la 
> memoria perteneciente a un proceso cuando éste termina. Como se ha 
> dicho, la memoria compartida con otros procesos no se eliminará, al 
> menos que ya no sea compartida. Sin embargo, todo esto es cuestión del 
> sistema operativo y no tiene relación alguna con el lenguaje de C++ ni 
> con sus bibliotecas estándares.
> 
> > La única posible solución que se me ocurre es utilizar la función 
> > "atexit()" para registrar funciones que se encarguen de eliminar
> > dichos objetos antes de que finalmente se mate al proceso. Pero, ¿es
> > esto necesario?
> > 
> 
> La solución a este problema implica liberar la memoria antes de terminar 
> el programa. Podríamos registrar una función con 'atexit()' que realice 
> tal limpieza de memoria. Ahora bien, esto implicaría que tales punteros 
> son globales. Por ejemplo,
> 
> ListaObjetos3D *pLista;
> ...
> void liberar()
> {
> delete pLista; // o 'delete[]' si se trata de un array dinámico
> }
> 
> int main()
> {
> atexit( liberar );
> pLista = new ListaOjbetos3D;
> ...
> glutMainLoop();
> 
> return 0; // Nunca llegaremos
> }
> 
> Claro que es posible que tengamos que hacer lo mismo para una 
> terminación anormal. Podemos registrar la misma función para la señal de 
> aborto. Por ejemplo,
> 
> int main()
> {
> atexit( liberar );
> signal( SIGABRT, liberar );
> ...
> }
> 
> En tu caso, al usar GLUT, podrías liberar la memoria en un tiempo 
> determinado o debido a algún evento activado por el usuario a través de 
> un periférico, como es el teclado o el ratón.
> 
> 
> La otra solución es simplemente no tener ninguna memoria creada 
> explícitamente, sino a través de algún objeto. Por ejemplo,
> 
> struct Entorno
> {
> ListaObjetos3D *pLista;
> 
> Entorno() : pLista(0) { pLista = new ListaObjetos3D; }
> ~Entorno() { delete pLista; }
> };
> 
> Entorno entorno;
> ...
> int main()
> {
> ...
> }
> 
> Así no tendremos problemas de pérdida de memoria, porque el destructor 
> se llamará automáticamente al salir del programa.
> 
> 
> Espero haber aclarado la duda.
> 
> Steven
> 
> 
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ

_________________________________________________________________
Con Windows Live, puedes organizar, editar y compartir tus fotos.
http://www.microsoft.com/spain/windows/windowslive/products/photo-gallery-edit.aspx
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20090730/fd89f386/attachment.html>


Más información sobre la lista de distribución Cconclase