Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

177
Vistas
Liberar toda la memoria asignada en caso de falla

Estoy trabajando en un proyecto C (tarea para la escuela). Una de las demandas es que en caso de fallo de malloc() , el programa debe free() toda la memoria asignada y exit() .

Considere un caso donde la función A() construye una lista enlazada y en cada iteración llama a otra función, B() . Ahora, si ocurre una falla de malloc en B() , debe free() la memoria que asignó, pero la función A() también debería hacerlo.

Las cosas se complican bastante cuando tienes un árbol de llamadas a funciones mayor que dos.

En mi proyecto anterior, usé una bandera para notificar una falla de malloc(): si una función usa otra función que puede usar malloc() , debe verificar la bandera inmediatamente después. Funcionó, pero el código se volvió un poco desordenado.

¿Hay una solución ordenada para este problema?
Por supuesto, con las aplicaciones "reales" toda la memoria es desasignada por el sistema operativo, pero supongo que esta demanda es pedagógica.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Creo que el enfoque más fácil es crear un asignador personalizado (como alguien ya señaló en una publicación eliminada) para realizar un seguimiento de todas sus asignaciones, luego hacer un asignador personalizado, utilícelo para todas sus necesidades de memoria en montón.

si un malloc falla, tiene la lista de bloques previamente asignados al alcance de la mano.

por ejemplo (debe rehacer esto porque no es efectivo y debe optimizarse pero muestra el principio y la única compilación ocular)

 typedef struct { void* pMemory; /* for the allocated memory */ size_t size; /* for better debugging */ } MemoryBlock; #define MAXBLOCKS 1000 MemoryBlock myheap[MAXBLOCKS]; // global so zero:ed static int block = 0; void* myalloc(size_t size) { static int block = 0; // you should check vs MAXBLOCKS myheap[block].pMemory = malloc(size); myheap[block].size = size; // check if it failed. if ( myheap[block].pMemory == NULL ) { for (int i = 0; i < block; ++i) { myfree(myheap[i].pMemory); } fprintf( stderr, "out of memory\n"); exit(EXIT_FAILURE); } else { return myheap[block++].pMemory; } } void myfree(void* p) { for (int i = 0; i < block; ++i) { if ( p == myheap[i].pMemory ) { free(myheap[i].pMemory); myheap[i].pMemory = NULL; return; } } }
over 4 years ago · Santiago Trujillo Denunciar

0

Sí. La mejor (y convencional) forma es inicializar cada valor de puntero a cero. Luego configúrelo durante la asignación de malloc(). Ej: myPtr = malloc( 10 );

Será cero en caso de falla, y lo verifica. Y finalmente, cuando vas a liberar, siempre verificas el valor del puntero antes de llamar a free():

 if ( myPtr != 0 ) free( myPtr );

No hay necesidad de una bandera adicional.

over 4 years ago · Santiago Trujillo Denunciar

0

Puede buscar en la función atexit() para registrar el código que se ejecutará cuando finalice el programa. Dicho código puede verificar si hay algo que deba estar free() d.

Tenga en cuenta que atexit() no tiene forma de cancelar el registro. Por lo tanto, debe asegurarse de registrar cada función de limpieza solo una vez y de que haga lo correcto cuando no haya nada que limpiar.

 #include <stdlib.h> #include <stdio.h> int *ptr1; char *ptr2; int clean1_registered, clean2_registered; void clean1(void) { printf("clean1 called\n"); if (ptr1) { free(ptr1); ptr1 = NULL; } } void clean2(void) { printf("clean2 called\n"); if (ptr2) { free(ptr2); ptr2 = NULL; } } void B(void) { ptr2 = malloc(100); if (!clean2_registered) { atexit(clean2); } } void A(void) { ptr1 = malloc(100 * sizeof(int)); if (!clean1_registered) { atexit(clean1); } B(); } int main(int argc, char **argv) { A(); }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda