[C]Libération de la mémoire

Fermé
Huit - 9 août 2006 à 13:28
kilian Messages postés 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 - 22 avril 2008 à 19:30
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
A voir également:

12 réponses

mamiemando Messages postés 33435 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 décembre 2024 7 810
9 août 2006 à 18:17
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 lundi 30 janvier 2006 Statut Membre Dernière intervention 3 avril 2008 64
9 août 2006 à 14:16
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 lundi 30 janvier 2006 Statut Membre Dernière intervention 3 avril 2008 64
10 août 2006 à 09:38
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 33435 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 décembre 2024 7 810
10 août 2006 à 09:51
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 lundi 30 janvier 2006 Statut Membre Dernière intervention 3 avril 2008 64
10 août 2006 à 11:47
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 vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 298
10 août 2006 à 13:24
question.
Si je fait :
int *n;
n=(int)malloc(sizeof(int)*k);
free(n) suffit ?
0
mamiemando Messages postés 33435 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 décembre 2024 7 810
10 août 2006 à 13:36
Oui
0
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 lundi 30 janvier 2006 Statut Membre Dernière intervention 3 avril 2008 64
11 août 2006 à 11:44
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
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
Salut,

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

Merci
0
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
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 33435 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 décembre 2024 7 810
17 août 2006 à 19:29
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
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 8731 Date d'inscription vendredi 19 septembre 2003 Statut Modérateur Dernière intervention 20 août 2016 1 527
22 avril 2008 à 19:30
Salut,

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