[C] -> Problème de free()

Fermé
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 - 13 déc. 2008 à 18:39
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 - 13 déc. 2008 à 22:12
Bonsoir a tous,

voila je fais un programme et j'ai un problème au niveau d'une fonction,
si j'appelle la fonction "Destruction_Fourmiliere" dans le "main" aucun soucis,
par contre si je l'appelle dans la fonction "Tour_Suivant" la j'ai ce message :
==8646== Invalid read of size 4
==8646==    at 0x804A58E: Tour_Suivant (in /home/brachior/MLV/Projets/Test)
==8646==    by 0x804A69D: main (in /home/brachior/MLV/Projets/Test)
==8646==  Address 0x42da420 is 40 bytes inside a block of size 48 free'd
==8646==    at 0x4024B4A: free (vg_replace_malloc.c:323)
==8646==    by 0x80490FF: Destruction_Fourmiliere (in /home/brachior/MLV/Projets/Test)
==8646==    by 0x804A3EB: Tour_Suivant (in /home/brachior/MLV/Projets/Test)
==8646==    by 0x804A69D: main (in /home/brachior/MLV/Projets/Test)

voici les prototypes des deux fonctions :

void Tour_Suivant(Monde *M,int numTour,FListe Eqp_tmp);
void Destruction_Fourmiliere(Monde *M,FListe F);

Monde étant une structure comprenant une liste (FListe) de fourmis.
et "Destruction_Fourmiliere" fait des free();

Merci pour l'aide ^^
A voir également:

1 réponse

Si tu as un problème avec free... va chez orange! :D

Soyons sérieux.
On n'en sait pas assez pour avoir un diagnostic.
D'une manière générale, il faut d'abord vérifier:
- si il y a autant d'allocations que de désallocations
- que les pointeurs alloués sont bien ceux qui sont désalloués.
0
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46
13 déc. 2008 à 19:16
Merci pour ta réponse ...

ouai j'aimerai éviter de mettre le code
d'une part car c'est un projet pour ma fac ...
et de deux y a plus de 600lignes a mettre =/

mais y a autant d'alloc que de free
==8980== 
==8980== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 1)
==8980== malloc/free: in use at exit: 0 bytes in 0 blocks.
==8980== malloc/free: 20 allocs, 20 frees, 1,264 bytes allocated.
==8980== For counts of detected errors, rerun with: -v
==8980== All heap blocks were freed -- no leaks are possible.


Et je sais bien que je free pas le bon pointeur ...
j'm'explique :
je pointe une Équipe contenant des fourmilières ( liste doublement chainées )
je veux free une fourmilière mais en gardant mon pointeur sur l'Equipe,

Au debut j'envoyai le vrai pointeur et faisais un Temp de mon Équipe, il me perdait mon pointeur ...
j'avais la meme erreur ... ( Mais j'arrive pas a free tout )

La j'ai envoyé une copie du pointeur et pareil
et meme en faisant un Temp de la copie de mon pointeur ...

Y a rien a faire il me perd mon pointeur et me met en plus ce message d'erreur -__-
0
loupius > Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009
13 déc. 2008 à 21:09
Je ne vois pas où se trouve la difficulté.
Si j'ai bien compris:
- Equipe contient une liste de Fourmilières et il faut supprimer une Fourmilière.
- il suffit de récupérer, dans la liste, le pointeur de la Fourmilière voulue, de supprimer cette entrée dans la liste et ensuite de libérer la mémoire désignée par ce pointeur.
0
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46 > loupius
13 déc. 2008 à 21:37
C'est ce que je fais ...
Et ca fonctionne très bien si je lance cette fonction dans le main ...
mais pas si je lance la fonction dans une autre fonction =/

( et disons que la partie un peu plus marrante vient du fait que
chaque fourmilière est une tête de liste doublement chainée )

et encore merci de t'intéresser a mon problème :)
0
loupius > Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009
13 déc. 2008 à 21:51
Si la fonction est correcte, il n'y a aucune raison (à priori) pour qu'elle fonctionne dans le main et pas ailleurs.
Si j'avais ce problème, voilà comment je réagirais:
- la fonction ne fonctionne pas tout le temps ---> donc elle est incorrecte.
- et si elle fonctionne dans le main, c'est tout simplement que les problèmes de pointeurs sont des problèmes souvent aléatoires; c'est-à-dire qu'une telle erreur ne se manisfeste que dans certaines conditions et pas toujours. Il arrive qu'une erreur de ce type arrive systématiquement dans le déroulement du programme, alors on passe sous debugger... et l'erreur ne se manisfeste plus! C'est la raison pour laquelle il faut être des plus rigoureux dans l'utilisation des pointeurs et c'est aussi la raison pour laquelle, certains ont horreur des pointeurs.... et du language C (pour moi c'est la meilleur!!!).
A moins de voir le code, je ne peux en dire plus (mais j'ai pas non plus envie de déchiffrer 600 lignes de code).
0
Brachior Messages postés 613 Date d'inscription dimanche 21 octobre 2007 Statut Membre Dernière intervention 22 juin 2009 46 > loupius
13 déc. 2008 à 22:12
Bon ... je vais te faire un p'tit compressé ^^

tout d'abord les structure
typedef struct four{
  ...
  struct four *fsuiv,*fprec; /* liste des fourmis liée à une fourmilière */
  struct four *vsuiv,*vprec; /* liste des fourmilieres voisines */
}Fourmi,*FListe;

typedef struct{
  ... 
/* FListe est un pointeur sur une liste de fourmi ( comme dit precedement ^^ ) */
  FListe Rouge,Noir;
}Monde;

puis les fonctions
void Destruction_Fourmiliere(Monde *M,FListe F){ 
 /* Detruit une fourmiliere et ses agents */

  ... /* raccrochage des fourmilieres suivante et precedente etre elles */

  free(F);
}

void Tour_Suivant(Monde M,int numTour){
  Fourmi *Fourmi_tmp = NULL; /* Index provisoire */
  FListe Eqp_tmp = M.Rouge; /* Temp sur l'equipe */
  while(Eqp_tmp != NULL){
 /* Dans la 1ere boucle, on parcours les fourmilieres */
    Fourmi_tmp = Eqp_tmp;
    while(Fourmi_tmp != NULL){
 /* Dans la 2eme, les fourmis en lien avec la fourmiliere */

...

            if(Fourmi_tmp->vprec != NULL){
              FListe Fourmiliere_tmp = Fourmi_tmp->vprec;
              Destruction_Fourmiliere(&M,Fourmi_tmp);
              Fourmi_tmp = Fourmiliere_tmp;
            }
            else
              Destruction_Fourmiliere(&M,Fourmi_tmp);
            Fourmi_tmp = NULL;
            fprintf(stderr,"Fourmiliere Supprimee\n");

...

      }
      if(Fourmi_tmp != NULL)
        Fourmi_tmp = Fourmi_tmp->fsuiv;
      }
      if(Eqp_tmp != NULL)
        Eqp_tmp = Eqp_tmp->vsuiv;
  }
}

/**** Le Main ****/
int main(void){
  Monde M;
  int numTour;
  Ini_Monde(&M);
  M.Rouge = NULL;
  M.Noir = NULL;
  Ini_Equipe(&M);

...

/* Si je fais ca, ca passe niquel */
  Destruction_Fourmiliere(&M,M.Rouge);

/* Mais ca, ca affiche le message d'erreur */
  Tour_Suivant(M,numTour);

/* Il est biensur evident que je ne fais pas les deux en meme temps
           ( meme si ca ne devrait pas poser probleme Oo */

...

  return 0;
}

Voila, si tu vois l'erreur Oo
0