LinkedList – Comment libérer la mémoire allouée avec malloc

J’ai un code C très simple pour construire une liste à lien simple comme ci-dessous, dans lequel j’alloue de la mémoire pour chaque nœud de manière dynamic à l’aide de malloc. À la fin du code, je souhaite libérer la mémoire de chaque nœud alloué, me demandant comment procéder. Si je pars d’abord du nœud principal et que je le libère, les pointeurs des nœuds suivants sont perdus et une fuite de mémoire se produit.

Vous pouvez également commencer à partir du noeud principal et continuer à stocker le pointeur de noeud dans un tableau séparé de pointeurs ou quelque chose de ce genre, parcourir la liste jusqu’au pointeur de queue tout en stockant les pointeurs de noeud et atteindre le noeud de queue pointeurs et libérez l’index de cette masortingce vers l’arrière jusqu’à ce que le nœud principal soit libéré.

Est-ce la seule façon de réaliser ce que j’essaie de faire?

Au cas où je ne voudrais pas utiliser le deuxième tampon, comment puis-je m’y prendre.

#include "stdio.h" #include "stdlib.h" struct lnk_lst { int val; struct lnk_lst * next; }; typedef struct lnk_lst item; main() { item * curr, * head; int i,desired_value; head = NULL; for(i=1;ival = i; curr->next = head; head = curr; } curr = head; while(curr) { printf("%d\n", curr->val); curr = curr->next; } //How to free the memory for the nodes in this list? for(i=1;i<=10;i++) { free()//?? What logic here } } 

    La manière habituelle est avec (pseudo-code en premier):

     node = head # start at the head. while node != null: # traverse entire list. temp = node # save node pointer. node = node.next # advance to next. free temp # free the saved one. head = null # finally, mark as empty list. 

    L’idée de base est de rappeler le nœud à libérer dans une variable distincte, puis de passer à la suivante avant de la libérer.

    Vous devez uniquement vous souvenir d’ un nœud à la fois, pas de la liste complète telle que vous la proposez.

    En ce qui concerne ce que vous devez append à votre code, vous pouvez, lors de la suppression, utiliser head comme head de liste à mise à jour continue (comme il se doit) et curr pour stocker l’élément que vous supprimez actuellement:

     while ((curr = head) != NULL) { // set curr to head, stop if list empty. head = head->next; // advance head to next element. free (curr); // delete saved pointer. } 

    C’est un peu plus court que le pseudo-code ci-dessus simplement parce qu’il tire parti du “raccourci” de C pour certaines opérations.

    J’utilise quelque chose comme ça:

     for (p = curr; NULL != p; p = next) { next = p->next; free(p); } 

    Votre code gratuit devrait être comme suit:

     lnk_lst temp = null; while(head) { temp = head->next; free(head); head = temp; } 

    Aussi, je voudrais append après votre malloc que vous voulez probablement vérifier si le mem a été alloué avec succès .. quelque chose comme

     if(curr) 

    Vous parcourez la liste en utilisant la même logique que ci-dessus. Vous enregistrez le pointeur curr-> suivant quelque part, vous libérez la structure curr et vous affectez le pointeur actuel au pointeur-> suivant

    Contenu de Garbage Collector.h

     #define Stack struct _stack #define _MALLOC_S(type,num) (type *)_GC_malloc(sizeof(type)*num) #pragma pack(1) //Structure for adressing alocated memory into. Stack { int *adress_i; char *adress_c; float *adress_f; double *adress_d; Stack *next; }; //Safe malloc void *_GC_malloc(size_t size) { void* ptr = malloc(size); if(ptr == NULL) return _GC_malloc(size); else return ptr; } //Push new element on Stack after every malloc void Add_New(int *i, float *f , double *d , char *c , Stack *p) { Stack *q = _MALLOC_S(Stack,1); q->adress_i = i; q->adress_f = f; q->adress_c = c; q->adress_d = d; q->next = p->next; p->next = q; q = NULL; } //before ending program remove adresses that was allocated in memory, and pop entire Stack void Free_All(Stack *p) { //free head (dummy element) Stack *Temp = p->next; Stack *_free = p; free(_free); void *oslobodi; while(Temp != NULL) { _free = Temp; Temp = _free->next; if(_free->adress_i != NULL){ oslobodi = _free->adress_i; free((int *)oslobodi); } else if(_free->adress_c != NULL){ oslobodi = _free->adress_c; free((char *)oslobodi); } else if(_free->adress_f != NULL){ oslobodi = _free->adress_f; free((float *)oslobodi); } else{ oslobodi = _free->adress_d; free((double *)oslobodi); } free(_free); } _free = p = Temp; } /* declare variable (var) and dinamicly alocate memory with simple macro, and add to stack of linked list */ #define obj_int(var) int *var = _MALLOC_S(int,1); *var = 0; Add_New(var, NULL, NULL, NULL, Head); #define obj_char(var) char *var = _MALLOC_S(char,1); *var = 0; Add_New(NULL, NULL, NULL, var, Head); #define obj_float(var) float *var = _MALLOC_S(float,1); *var = 0; Add_New(NULL, var, NULL, NULL, Head); #define obj_double(var) double *var = _MALLOC_S(double,1); *var = 0; Add_New(NULL, NULL, var, NULL, Head); #define obj_struct(_type,_name) struct _type _*name = (struct _type *)malloc(sizeof(struct _type)); #define _INIT_ROW(var,num) for(int i = 0; i < num; i++) var[i] = 0; /* same, but for row! */ #define row_int(var, num) int *var = _MALLOC_S(int,num); _INIT_ROW(var,num) Add_New(var, NULL, NULL, NULL, Head); #define row_char(var, num) char *var = _MALLOC_S(char,num); _INIT_ROW(var,num) Add_New(NULL, NULL, NULL, var, Head); #define row_float(var, num) float *var = _MALLOC_S(float,num); _INIT_ROW(var,num) Add_New(NULL, var, NULL, NULL, Head); #define row_double(var, num) double *var = _MALLOC_S(double,num); _INIT_ROW(var,num) Add_New(NULL, NULL, var, NULL, Head); #define string(var, value) row_char(var, (strlen(value)+1)) strcpy(var, value); /* with this you create a Stack and allocate dummy element */ #define Main(_type) _type main(void) { Stack *Head = _MALLOC_S(Stack,1); Head->next = NULL; Stack *_q_struct; /* with this macro you call function for dealocate memory (garbage collecting)*/ #define End Free_All(Head); } /*same thing for the other functions*/ #define Function(name_function, _type, ...) _type name_function(##__VA_ARGS__) { Stack *Head = _MALLOC_S(Stack,1); Head->next = NULL; #define End_Ret(ret_var) Free_All(Head); return (ret_var); } #define Call(name_function, ...) name_function(##__VA_ARGS__) #define Define_Function(name_function, _type, ...) _type name_function(##__VA_ARGS__); 

    Exemple de some_program.c en-tête PS systemIO est un groupe de plusieurs en-têtes comme celui-ci ci-dessus! 🙂

     #include  Main(void) int num_elements = 10; row_int(row_elements, num_elements); //alocating row_elements object for(int i = 0; i < num_elements; i++) row_elements[i] = i; //initializing row_elements End //Garbage delete row_elements and end of program // row_int[0] = 0, row_int[1] = 1 ....