Rechercher : dans
Par :

[C]Libération de la mémoire

Dernière réponse le 22 avr 2008 à 19:30:21 Huit, le 9 aoû 2006 à 13:28:13 
 Signaler ce message aux modérateurs

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

Meilleures réponses pour « [C]Libération de la mémoire » dans :
Les tableaux en langage C++ VoirType de données complexes Les variables, telles que nous les avons vues, ne permettent de stocker qu'une seule donnée à la fois. Or, pour de nombreuses données, comme cela est souvent le cas, des variables distinctes seraient beaucoup trop lourdes...
Carte mémoire (mémoire Flash) VoirIntroduction à la mémoire Flash La mémoire flash est une mémoire à semi-conducteurs, non volatile et réinscriptible, c'est-à-dire une mémoire possédant les caractéristiques d'une mémoire vive mais dont les données ne se volatilisent pas lors...
Langage C - Les types de données VoirLes types de données Les données manipulées en langage C sont typées, c'est-à-dire que pour chaque donnée que l'on utilise (dans les variables par exemple) il faut préciser le type de donnée, ce qui permet de connaître l'occupation mémoire (le...

2

Darshu, le 9 aoû 2006 à 14:16:53

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 !

T'as pensé à regarder sur Google avant de poser ta question ? 

Répondre à Darshu

3

mamiemando, le 9 aoû 2006 à 18:17:10

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

Répondre à mamiemando

4

Darshu, le 10 aoû 2006 à 09:38:42

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 !

T'as pensé à regarder sur Google avant de poser ta question ­? 

Répondre à Darshu

5

mamiemando, le 10 aoû 2006 à 09:51:28

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

Répondre à mamiemando

6

Darshu, le 10 aoû 2006 à 11:47: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 ^-^

T'as pensé à regarder sur Google avant de poser ta question ­? 

Répondre à Darshu

Char Snipeur, le 10 aoû 2006 à 13:24:33

Question.
Si je fait :
int *n;
n=(int)malloc(sizeof(int)*k);
free(n) suffit ? Salutation !
Char Snipeur

Répondre à Char Snipeur

7

mamiemando, le 10 aoû 2006 à 13:36:34

Oui

Répondre à mamiemando

8

Huit, le 11 aoû 2006 à 11:20:42

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;
}

Répondre à Huit

9

Darshu, le 11 aoû 2006 à 11:44:10

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 !

T'as pensé à regarder sur Google avant de poser ta question ? 

Répondre à Darshu

11

Radek, le 17 aoû 2006 à 15:27:20

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);
}

Répondre à Radek

10

Huit, le 17 aoû 2006 à 11:07:51

Salut,

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

Merci

Répondre à Huit

12

Radek, le 17 aoû 2006 à 15:32:22

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.

Répondre à Radek

13

Radek, le 17 aoû 2006 à 15:34:42

Personnellement, je ne vois pas l'interet de ta structure Graphe si elle ne contient qu'un pointeur sur ta structure Noeud...

Répondre à Radek

14

mamiemando, le 17 aoû 2006 à 19:29:24

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

Répondre à mamiemando

15

djess, le 19 avr 2008 à 18:57:11

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)!!

Répondre à djess

16

 kilian, le 22 avr 2008 à 19:30:21

Salut,

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

Répondre à kilian
Collection CommentÇaMarche.net