Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

178
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!