[C]Libération de la mémoire

Huit -  
kilian Messages postés 8732 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,

je voudrais savoir comment se passe la libération de la mémoire pour des char **, char ***, struct nom **, etc
Par exemple, dans mon cas, j'ai 2 structures :
typedef struct noeud{ 
int n; 
struct noeud **tab; 
}Noeud; 

typedef struct{ 
Noeud *racine; 
}Graphe;

Comment s'écrirait la fonction
int libérerGraphe(Graphe **g)
permettant de libérer un graphe.

Merci

12 réponses

mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884
 
En fait c'est presque ça mais tu n'as pas tout désalloué. Supposons qu'on ait une matrice de pointeurs int*, la matrice est donc un int***. On va mettre tout ça dans une structure permettant de connaître le nombre de ligne et de colonne.
struct matrix{
  int ***data; // une matrice 2D de int *
  unsigned int nb_lig; // nb de ligne
  unsigned int nb_col; // nb de colonne
};

Ensuite il faut :
1) désallouer les int *
2) désallouer les int ** (chaque tableau correspondant à une ligne de matrice)
3) désallouer le int *** (le tableau de lignes)
struct matrix m;

//je remplis m, en tenant à jour m.nb_lig et m.nb_col
// ...
// et je désalloue

for(i=0;i<nb_lig;++i){
  for(j=0;j<nb_col;++j){
    free(m[i][j]); // je désalloue le int * m[i][j]
  }
  free(m[i]); // je désalloue le int ** (la ligne m[i])
}
free(m); // je désalloue le int *** qui pointe désormais sur une zone vide

Bonne chance
4
Darshu Messages postés 303 Date d'inscription   Statut Membre Dernière intervention   64
 
Salut.

Pour libérer des trucs dans le tas, il faut faire free() sur chaque élément. Par exemple, tu as
int *n;
n=(int *)malloc(sizeof(int)*k);
Alors pour libérer la mémoire tu fais
for (i=0 ; i<k ; i++)
   free(n[i]);
Le principe est le même pour des int ** mais avec une double boucle et un free sur n[i][j].

Pour libérer un graphe, utilises les pointeurs (2 ici). Tu fais un free sur le premier élément, mais un pointeur garde l'adresse de l'élément suivant en mémoire. Et tu continues à boucler tant que le pointeur qui indique l'élément suivant n'est pas NULL.

Bon courage !
1
Darshu Messages postés 303 Date d'inscription   Statut Membre Dernière intervention   64
 
Vraiment ? Je n'ai jamais désalloué les intermédiaires, soit m[i] et m ... J'ai toujours entendu dire que free(m[i][j]) suffisait !
0
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884
 
Ben je vois pas quand est ce que tu desalloues les "intermédiaires" alors... C'est simple en C à chaque malloc, tu dois associer un free. Vu que tu as mallocé les intermédiaires tu dois les libérer... En cas de doute tu peux utiliser par exemple valgrind pour vérifier si tu libères toute la mémoire.

Note également que si le free était inutile le programme planterait (double free) mais là, je suis à peu près certaine de mon coup ;-)

Bonne chance
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Darshu Messages postés 303 Date d'inscription   Statut Membre Dernière intervention   64
 
C'est vrai qu'il y a un malloc sur les intermédiaires ... Et que ça planterait sinon ! J'ai appris quelque chose aujourd'hui au moins, merci ^-^
0
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
question.
Si je fait :
int *n;
n=(int)malloc(sizeof(int)*k);
free(n) suffit ?
0
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884
 
Oui
0
Huit
 
Dans le cas de mes structures, la libération du graphe, se fait de cette manière ?

MAXNOEUDS est le nombre de fils max que peut avoir un sommet
int libereNoeud(Noeud *n){
  int i;
  for(i=0; i<MAXNOEUDS ;i++){
    if((n->tab[i])!=NULL){
      libereNoeud(n->tab[i]);
      free(n->tab[i]);
    }
  }
  free(n);
  return 1;
}

int libereGraphe(Graphe **g)
{
  if(*g != NULL)
    {
      libereNoeud(*g->racine);
      free(*g);
    }
  
  free(g);

  return 1;
}
0
Darshu Messages postés 303 Date d'inscription   Statut Membre Dernière intervention   64
 
J'aime pas trop la récursivité dans une boucle for personnellement ... Tu t'es embrouillé les pinceaux la :)

Pour une simple liste chaînée, tu fais
void libereListe(liste *ptr)
{
   pt_suivant = ptr->ptsuiv
   while ( pt_suivant != NULL)
   {
      pt_var = pt_suivant;
      free(pt_var);
      pt_suivant = pt_suivant->ptsuiv;
   }
   free(ptr);
}
Si ta liste a comme pointeur suivant ptsuiv. Il ne te reste plus qu'à garder cette philosophie ... Mais un simple while suffit !
0
Radek
 
Je pense qu'il faut peut être récupérer le ptr suivant avant de l'effacer ! non ? ;)
Ton bout de code marchera sur certain compilo peu respectables, mais pas sur tous !!!

void libereListe(liste *ptr)
{
pt_suivant = ptr->ptsuiv
while ( pt_suivant != NULL)
{
pt_var = pt_suivant->ptsuiv;
free(pt_suivant);
pt_suivant = pt_var;
}
free(ptr);
}
0
Huit
 
Salut,

est-ce que quelqu'un pourrait me corriger en utilisant la structure que j'ai écrit ?

Merci
0
Radek
 
Tout dépends comment tu gère tes structures et tes ptrs. Si tu veux un coup de main donne plus de détails sur la création de tes structures.
0
Radek
 
Personnellement, je ne vois pas l'interet de ta structure Graphe si elle ne contient qu'un pointeur sur ta structure Noeud...
0
mamiemando Messages postés 33778 Date d'inscription   Statut Modérateur Dernière intervention   7 884
 
Je suis assez d'accord. Je pense qu'il a dû repartir d'une structure d'arbre. Pour moi un graphe c'est :
- une map <vertex_id, pointeur sur le vertex> sur la structure du vertex, où le vertex_id est un entier unique associé à un sommet
- une map <edge_id,pointeur sur le edge> où le edge_id est un entier unique associé à un arc
- une structure d'adjacence, typiquement une liste d'adjacence ou une matrice d'adjacence, contenant à la case [id_source][id_dest] l'identifiant de l'arc

A côté de ça et complètement indépendamment de la notion d'adjacence liée au graphe, on définit une structure vertex et une structure edge contenant uniquement les informations qu'ils encapsulent (par exemple le nom du sommet, le poids associé à un arc).

Si ce type de structure peut paraître de prime abord un peu alambiqué c'est qu'en fait qu'elle premet d'écrire une structure de graphe aussi générique que possible. C'est d'ailleurs sur ce principe que fonctionne la BGL (lib boost pour les graphes).

Libre à toi d'utiliser la structure qui te convient le mieux... sachant qu'en C++ ce sera beaucoup plus simple à écrire.

Bonne chance
0
djess
 
slt,g un probleme avec free(),j'essaye de liberer l'espace memoire pointé par la variable A qui est un pointeur sur une structure, et free(A); ça marche pas!!
en fait,je travaille sur les arbres (si ça pourrait aider)!!
0
kilian Messages postés 8732 Date d'inscription   Statut Modérateur Dernière intervention   1 526
 
Salut,

Poste ton message dans un nouveau sujet pour que l'on puisse répondre à ce nouveau problème.
0