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 :

plantage lors de mon free


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut plantage lors de mon free
    Bonjour, je ne comprends pas la cause du plantage de mon prgm. Je fais free(mon_vecteur) et là il plante. Voici le bout de code de mon main qui pause problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    char * name_file="therm.dat"; /* file containing thermodynamic data */
    Species ** TabSpecies=malloc(nb_especes_*sizeof(*TabSpecies));
     assert(TabSpecies!=NULL);
     
    for(i=0;i<nb_especes_;++i)
    {               
        printf("zut\n");     
       TabSpecies[i]=CreateEmptySpecies();
       printf("zut2\n");
      LoadSpecies(name_file,NameSpecies[i],TabSpecies[i]);
      printf("zut3\n");
    }
    il affiche bien zut mais pas zut2, donc je suis allé dans ma fonction CreateEmptySpecies qui voici

    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
    29
    30
    31
     
    Species * CreateEmptySpecies(void)
    {
        Species * s=malloc(sizeof(*s));
        assert(s!=NULL);
        s->name="no name";
        s->M=0.0;
        s->T=0.0;
        if(s->LT!=NULL) 
       {
         printf("tyty\n");
         free(s->LT);
       }
        s->LT=malloc(7*sizeof(*s->LT));
        assert(s->LT!=NULL);
        printf("tata\n");
        if(s->HT!=NULL)
        {
           printf("tete\n");
          free(s->HT);
          printf("tete2\n");
       }
       printf("tata\n");
        s->HT=malloc(7*sizeof(*s->HT));
        assert(s->HT!=NULL);
        int i;
        for(i=0;i<7;++i)
    	s->LT[i]=s->HT[i]=0.0;
     
        return s;
    }
    Là il affiche tata et tete. j'ai donc deux question : pourquoi mon free(s->HT) ne marche pas ? et pourquoi s->LT est NULL mais s->HT n'est pas NULL ? Je vous envoie mon species.h

    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
     
    #ifndef _SPECIES_H_
    #define _SPECIES_H_
     
    typedef struct {
        char * name; /* name */
        double M;    /* molar mass */
        double T;    /* critical temperature */
        double * LT; /* 7 low temperature coefficients */
        double * HT; /* 7 high temperature coefficients */
    } Species;
     
    Species * CreateEmptySpecies(void);
    Species * CreateSpecies(char *,double,double,double *,double *);
    void PrintSpecies(Species *);
    void DestroySpecies(Species *);
    void LoadSpecies(char *,char *,Species *);
     
    #endif
    Merci.

  2. #2
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut Re: plantage lors de mon free
    Bonjour,

    Citation Envoyé par salseropom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Species ** TabSpecies=malloc(nb_especes_*sizeof(*TabSpecies));
     assert(TabSpecies!=NULL);
    C'est dommage de tester le retour de malloc qu'en phase de developpement, généralement si ça échouée c'est chez le client.

    Citation Envoyé par salseropom
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        if(s->LT!=NULL) 
       {
         printf("tyty\n");
         free(s->LT);
       }
    s->LT n'est pas initialisé (un compilateur bien réglé devrait te le dire)

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Species * CreateEmptySpecies(void) 
    { 
        Species * s=malloc(sizeof(*s)); 
    ......
        if(s->LT!=NULL) 
       {
    s->SLT n'a pas été initialisée et contient n'importe quoi. Le free(s->SLT) va planter. C'est miracle que s->SLT soit par hasard NULL
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
         ...
         free(s->LT); 
       } 
        s->LT=malloc(7*sizeof(*s->LT)); 
        ......
        if(s->HT!=NULL) 
        {
    Même remarque mais comme il a affiché tete, le miracle ne s'est pas reproduit et il plante sur free(s->HT)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
           printf("tete\n"); 
          free(s->HT); 
          printf("tete2\n"); 
       }
    .... 
    }
    Le code devrait simplement être qq chose du genre
    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
    Species * CreateEmptySpecies(void) 
    { 
        int i;
        Species * s=malloc(sizeof(*s)); 
        assert(s!=NULL); 
        s->name=NULL
        s->M=0.0; 
        s->T=0.0; 
        s->LT=malloc(7*sizeof(*s->LT)); 
        assert(s->LT!=NULL); 
        s->HT=malloc(7*sizeof(*s->HT)); 
        assert(s->HT!=NULL); 
        for(i=0;i<7;++i) 
         s->LT[i]=s->HT[i]=0.0; 
        return s; 
    }

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Bonjour, mercis pour vos réponses, je vais modifier mon code immédiatement.
    Est-ce à cause de ces "miracles" que si je déplaçais ce bloque ailleurs dans mon main, mon prgm fonctionne très bien ?

  5. #5
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par salseropom
    Bonjour, mercis pour vos réponses, je vais modifier mon code immédiatement.
    Est-ce à cause de ces "miracles" que si je déplaçais ce bloque ailleurs dans mon main, mon prgm fonctionne très bien ?
    Oui ça s'appel un comportement indéfini, ça va du plantage (le rêve, au moins c'est visible) ou comportement parfaitement normal jusqu'au changement d'ordi/plateforme : les joies du C

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Est-ce à cause de ces "miracles" que si je déplaçais ce bloque ailleurs dans mon main, mon prgm fonctionne très bien ?
    Probablement. C'est une malchance car le programme est sérieusement vérolé mais semble fonctionner. Il aurait planté un jour ou l'autre.

    gege2061 : C'est dommage de tester le retour de malloc qu'en phase de developpement, généralement si ça échouée c'est chez le client.
    Tu devrais tenir compte de cette judicieuse remarque

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Re, et que veut dire la remarque

    gege2061 : C'est dommage de tester le retour de malloc qu'en phase de developpement, généralement si ça échouée c'est chez le client.
    Merci.

  8. #8
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    assert() n'est generalement inclus dans l'executable final qu'en mode 'debug'. En compilation finale (release), l'assert n'est pas inclus et le test n'est pas effectue.
    Cela depend du compilateur utilise, cependant.

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par DaZumba
    assert() n'est generalement inclus dans l'executable final qu'en mode 'debug'. En compilation finale (release), l'assert n'est pas inclus et le test n'est pas effectue.
    Cela depend du compilateur utilise, cependant.
    Euh ça ne dépend pas plutot si la macro NDEBUG est définie ou non ?

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    mais alors que dois faire pour vérifier si tous mes malloc n'ont pas échouer ?
    Dois faire qqch du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    fprintf(stderr,"erreur dans %s ligne %d fonction %s : pb d'allocation de mémoire\n",__FILE__,__LINE__,__FUNCTION__);
    exit(1);
    et ainsi j'ai enlevé mon assert ?

  11. #11
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par gege2061
    Euh ça ne dépend pas plutot si la macro NDEBUG est définie ou non ?
    C'est exact. Je ne souhaitais pas rentrer dans les details.

    Citation Envoyé par salseropom
    mais alors que dois faire pour vérifier si tous mes malloc n'ont pas échouer ?
    Un test que la valeur retournee n'est pas nulle, puis on s'occupe de l'erreur. Ton exit() est un peu trop violent a mon gout (mais atexit() peut etre utile).
    Personnellement, je prefere remonter un code d'erreur a main() qui s'occupe de liberer la memoire allouee et de fermer les fichiers eventuellement ouverts. On peut aussi creer des systemes plus complexes, type garbage collectors, qui se chargent d'essayer de trouver de la memoire en liberant des objets inutilises, puis on retente le malloc().

  12. #12
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    là j'avoue que ca dépasse mes capacités du C. Je vais changer mes exit(1) en return 1 mais le garbage collectors me dépasse...

  13. #13
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par salseropom
    le garbage collectors me dépasse...
    Oh oui, je n'en fais jamais moi non plus. Je disais juste qu'il existe d'autres techniques que "j'ai echoue une fois, je quitte". Mais c'est autrement plus complexe, comme je disais.

  14. #14
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par DaZumba
    Citation Envoyé par gege2061
    Euh ça ne dépend pas plutot si la macro NDEBUG est définie ou non ?
    C'est exact. Je ne souhaitais pas rentrer dans les details.
    Oui et il se trouve qu'avec VC++6, par exemple, en mode Release, la macro NDEBUG est définie.

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom
    mais alors que dois faire pour vérifier si tous mes malloc n'ont pas échouer ?
    Dois faire qqch du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    fprintf(stderr,"erreur dans %s ligne %d fonction %s : pb d'allocation de mémoire\n",__FILE__,__LINE__,__FUNCTION__);
    exit(1);
    et ainsi j'ai enlevé mon assert ?
    C'est une façon de faire, mais c'est un peu violent. On préfère remonter l'info (pointeur NULL) 'au-dessus' et laisser la couche supérieure prendre la décision.

    Exemple :

    http://emmanuel-delahaye.developpez.com/tad.htm

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 298
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 298
    Points : 886
    Points
    886
    Par défaut
    Bon, j'ai vais réfléchir à tout ça alors. Mais j'avoue que je n'ai pas encore votre niveau donc il y a certaines choses qui me dépassent.

    Merci encore.

  17. #17
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par salseropom
    Mais j'avoue que je n'ai pas encore votre niveau donc il y a certaines choses qui me dépassent.
    Il n'y a pas besoin d'un niveau particulier pour utiliser malloc(), tester le retour, initialiser ses variables avant de les utiliser etc.

    Si tu trouves ça compliqué, aborde les sujets un par un en faisant des exercices qui n'utililisent qu'un seul concept nouveau à la fois.

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

Discussions similaires

  1. Plantage lors d'un free
    Par Franck.H dans le forum C
    Réponses: 16
    Dernier message: 13/05/2013, 21h24
  2. pb avec mon free
    Par salseropom dans le forum C
    Réponses: 8
    Dernier message: 27/04/2006, 10h53
  3. Réponses: 22
    Dernier message: 28/03/2006, 14h59
  4. [Debutant(e)]Plantage grave de mon Eclipse
    Par nanas dans le forum Eclipse Java
    Réponses: 8
    Dernier message: 11/06/2004, 13h57
  5. plantage lors de réception de fihier
    Par marsupile dans le forum C++Builder
    Réponses: 9
    Dernier message: 22/01/2004, 18h08

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