IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Free et Segmentation fault


Sujet :

C

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Par défaut Free et Segmentation fault
    Bonsoir,

    Voici une partie de mon code qui me pose problème. Dans certains cas, une erreur de segmentation se produit au niveau de "free (mat[i])". Comment est-ce possible ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    typedef struct test {
      int **mat;
      int x;
      int y;
      int c;
     
      struct test *prec;
    } test_t;
     
    static void mat_free (int ** mat)
    {
      for (int i = 0; i < TAILLE; i++)
        free (mat[i]);
     
      free (mat);
    }
     
    static void pile_free(test_t *pile)
    {
      while (pile->prec != NULL)
        { 
          pile = pile->prec;
          pile_free(pile);
     
          mat_free(pile->mat);
          free(pile);
        }
    }
    Merci d'avance.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 81
    Par défaut
    Je pense que ta fonction pile_free ne libère que le premier élément de la pile vu que tu écrases la valeur du paramètre pile à chaque fois.
    Après, je sais pas si c'est ce qui provoque ton erreur sur free (mat[i]).

    [EDIT]
    J'ai peut-être dit une anêrie juste au-dessus. J'ai du mal avec le récursif

    Par contre, je trouve ça gênant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while (pile->prec != NULL)
    {
          ...
          free(pile);
    }
    J'aurais plutôt vu la fonction comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static void pile_free(test_t *pile)
    {
        if (pile->prec != NULL)
            pile_free(pile->prec);
     
        mat_free(pile->mat);
        free(pile);
    }
    [/EDIT]

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 35
    Par défaut
    Citation Envoyé par sam1507 Voir le message
    Je pense que ta fonction pile_free ne libère que le premier élément de la pile vu que tu écrases la valeur du paramètre pile à chaque fois.
    Après, je sais pas si c'est ce qui provoque ton erreur sur free (mat[i]).

    [EDIT]
    J'ai peut-être dit une anêrie juste au-dessus. J'ai du mal avec le récursif

    Par contre, je trouve ça gênant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    while (pile->prec != NULL)
    {
          ...
          free(pile);
    }
    J'aurais plutôt vu la fonction comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    static void pile_free(test_t *pile)
    {
        if (pile->prec != NULL)
            pile_free(pile->prec);
     
        mat_free(pile->mat);
        free(pile);
    }
    [/EDIT]
    Ce qui est génant c'est que tu ne delete toujours pas ton premier maillon de ta list.
    C'est ce que je trouve très gênan :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static void pile_free(test_t *pile)
    {
      while (pile->prec != NULL)
        { 
          pile = pile->prec; 
          pile_free(pile); 
     
          mat_free(pile->mat);
          free(pile); 
        }
    }
    Tu ne délete jamais ton premier maillon? Est-ce normal? et pourquoi faire appels a de la récursivité?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static void pile_free(test_t *pile)
    {
      test_t *memoPile;
      while (pile != NULL)
        {
          memoPile = pile; // Je retiens l'adresse de pile
          pile = pile->prec;  // Pile va sur un autre maillon de la chaine
          mat_free(memoPile->mat); // je free mon char ** de mon  maillon
          free(memoPile);   // je free mon maillon donc je perds l'information "prec" pour cela que j'ai gardé mon pointeur principal qui est a l'adresse deja du prochain maillon
        }
    }
    Voila je pense que tu n'auras plus de segfault avec ca
    Par contre si ta struct n'est pas une liste chaîné alors je me suis peut être gouré

  4. #4
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    90
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 90
    Par défaut
    Votre version itérative est parfaite, l'erreur de segmentation a en effet disparu. Merci.
    Mais y a t-il un moyen de la transformer de manière récursive ? car cela m'est imposé.

  5. #5
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    81
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 81
    Par défaut
    La version que je t'ai donné plus haut gardait la récursivité. Par contre, je l'ai pas testé donc je sais pas si elle marche

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2011
    Messages : 35
    Par défaut
    La version de sam1507 pour la récursivité est bonne (j'ai juste rajouté une petite vérification de la valeur d'entrée on ne sait jamais ce qui peut ce passer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static void pile_free(test_t *pile)
    {
        if (pile != NULL)
        {
            if (pile->prec != NULL)
               pile_free(pile->prec);
     
           mat_free(pile->mat);
           free(pile);
       }
    }
    As-tu compris pourquoi le while est inutile dans cette récursivité?
    As-tu compris pourquoi il ne fallait pas affecter la valeur de pile a pile->prec puis lancer la récursivité?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. free() qui provoque une segmentation fault
    Par bringer dans le forum Débuter
    Réponses: 16
    Dernier message: 19/11/2010, 17h46
  2. [SDL_Image] Img_Load : segmentation fault ....
    Par Mathieu.J dans le forum OpenGL
    Réponses: 6
    Dernier message: 19/10/2004, 23h52
  3. [REDHAT] Segmentation fault systematique
    Par mela dans le forum RedHat / CentOS / Fedora
    Réponses: 2
    Dernier message: 21/09/2004, 06h05
  4. Réponses: 13
    Dernier message: 13/07/2004, 15h41
  5. Comment contrer la "segmentation fault" ?
    Par guillaume_pfr dans le forum C
    Réponses: 15
    Dernier message: 08/08/2003, 13h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo