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 :

Erreur de compilation indebugable


Sujet :

C

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 12
    Par défaut Erreur de compilation indebugable
    Bonjour à tous,

    J'implémente actuellement la structure Tas, et j'obtient lors de la compilation sous Mac os X.5 l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tas(1376) malloc: *** error for object 0x100170: double free
    *** set a breakpoint in malloc_error_break to debug
    Ce qui est étrange c'est que sous Ubuntu ca se compile tous seule:

    Voila à quoi ressemble le module:

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <memoire.h>
    #include "tas.h"
     
    #define BLOC 4
     
     
    struct tas{
     
      int dernier;
      int taille_physique;
      int *arbreBinaire;
    };
     
    typedef struct tas *tas;
     
    tas
    creerTas(void){
     
      tas tas_cree=memoire_allouer(sizeof(struct tas));
     
      tas_cree->dernier=0;
      tas_cree->taille_physique=BLOC;
      tas_cree->arbreBinaire=memoire_allouer(BLOC*sizeof(int));
     
      return tas_cree;
    }
     
    void 
    libererTas(tas T)
    {
      memoire_liberer(T->arbreBinaire);
      memoire_liberer(T);
    }
     
    void
    agrandirTas(tas T)
    {
      while(T->dernier >= T->taille_physique)
        T->taille_physique += BLOC;
      memoire_reallouer(T->arbreBinaire, T->taille_physique *sizeof(T->arbreBinaire));
    }
     
    void
    insererValeur(tas T, int valeur)
    {
      if(T->dernier >= T->taille_physique)
        agrandirTas(T);
     
      T->arbreBinaire[T->dernier]=valeur;
      T->dernier=(T->dernier)+1;
      /*T->arbreBinaire[T->dernier]=valeur;*/
    }
     
    void
    afficheTas(tas T)
    {
      int nombre_element=T->dernier;
      for (int i=0; i < nombre_element; i++)
        printf("%d ", T->arbreBinaire[i]);
      printf("\n");
    }
     
     
    int
    main(int argc, char * argv[])
    {
      tas T=creerTas();
     
      insererValeur(T,5);
      insererValeur(T,7);
      insererValeur(T,5);
      insererValeur(T,7);
      insererValeur(T,5);
      insererValeur(T,7);
      insererValeur(T,5);
      insererValeur(T,7);
      insererValeur(T,5);
      insererValeur(T,7);
      insererValeur(T,5);
      insererValeur(T,7);
     
      afficheTas(T);
     
      printf("Taille physique= %d \n", T->taille_physique);
     
      libererTas(T);
     
      return EXIT_SUCCESS;
     
    }
    J'anticipe certaine question, memoire_allouer, memoire_reallouer et memoire_liberer ne sont rien d'autre que des malloc, realloc et free avec des assert derrière, le problème survient quand on utilise les fonctions classiques.

    Je remercie tous ce qui passeront un peu de temps dessus ...

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mommsse Voir le message
    J'implémente actuellement la structure Tas, et j'obtient lors de la compilation sous Mac os X.5 l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tas(1376) malloc: *** error for object 0x100170: double free
    *** set a breakpoint in malloc_error_break to debug
    Ce qui est étrange c'est que sous Ubuntu ca se compile tous seule:
    Déjà, il faut bien comprendre la nature de l'erreur signalée. Il s'agit d'une erreur d'exécution (et non de compilation) détectée par le système parce que tu libères 2 fois le même bloc. Il est recommandé, après la libération d'un bloc, de donner la valeur NULL au pointeur, car après le free(), l'adresse pointée devient invalide.

    NULL est une valeur connue et testable de pointeur invalide. De plus, free(NULL) est parfaitement défini par la norme (ne fait rien).

    Ton code ne compile pas. Il est incomplet (manque des headers...)

  3. #3
    Membre chevronné Avatar de corentin59
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    462
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 462
    Par défaut
    Je pense que la ligne suivante porte à confusion au niveau des pointeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef struct tas *tas;
    En fait, je ne sais pas trop ce que tu définies comme type de données. Perso, j'aurai plutôt fait comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
     
      int dernier;
      int taille_physique;
      int *arbreBinaire;
    } tas;
    ainsi, je peux faire les déclarations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    tas ex1;
    tas *ex2;
    où ex1 est bien une structure "tas" et ex2 un pointeur vers une structure "tas". Ensuite, dire explicitement que tes fonctions renvoies ou prennent en argument un pointeur vers une structure "tas".

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 12
    Par défaut
    C'est vrai, ce n'est pas une erreur de compilation mais bien d'execution, mais ce que je n'arrive pas à comprendre, c'est que lorsque je debug avec gdb, l'erreur survient 2 fois, et jamais lorsque je libere la memoire ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /*Allocation de la memoire */
    [memoire: 1 (0x100120)]
    [memoire: 2 (0x100170)]
    tas(1436) malloc: *** error for object 0x100170: double free
    *** set a breakpoint in malloc_error_break to debug
    5 7 5 7 5 7 5 7 5 7 5 7 
    Taille physique= 12 
    tas(1436) malloc: *** error for object 0x100170: double free
    *** set a breakpoint in malloc_error_break to debug
    /* Liberation de la memoire */
    [memoire: 1 (0x100170)]
    [memoire: 0 (0x100120)]

    J'arrive vraiment pas a comprendre d'ou ca vient ??

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 12
    Par défaut
    Citation Envoyé par corentin59 Voir le message
    Je pense que la ligne suivante porte à confusion au niveau des pointeurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef struct tas *tas;
    En fait, je ne sais pas trop ce que tu définies comme type de données. Perso, j'aurai plutôt fait comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
     
      int dernier;
      int taille_physique;
      int *arbreBinaire;
    } tas;
    ainsi, je peux faire les déclarations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    tas ex1;
    tas *ex2;
    où ex1 est bien une structure "tas" et ex2 un pointeur vers une structure "tas". Ensuite, dire explicitement que tes fonctions renvoies ou prennent en argument un pointeur vers une structure "tas".
    C'est ce que j'utilisais juste avant, le problème survient tout de même.

    typedef struct tas *tas;

    Je définis seulement tas comme un pointeur vers la structure tas.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 12
    Par défaut
    J'ai détecté l'erreur mais je ne la comprend pas:

    Elle survient lors du realloc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void
    agrandirTas(tas T)
    {
      while(T->dernier >= T->taille_physique)
        T->taille_physique += BLOC;
      realloc(T->arbreBinaire, T->taille_physique *sizeof(T->arbreBinaire));
    }
    Qu'est ce qui cloche pourquoi cette erreur ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tas(1624) malloc: *** error for object 0x100170: double free
    *** set a breakpoint in malloc_error_break to debug


    Et pourquoi cela ne survient-il que sous Leopard et pas sous Linux ?

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mommsse Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tas(1624) malloc: *** error for object 0x100170: double free
    *** set a breakpoint in malloc_error_break to debug


    Et pourquoi cela ne survient-il que sous Leopard et pas sous Linux ?
    Chaque plateforme est libre tester ce qu'elle veut...

  8. #8
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par mommsse Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void
    agrandirTas(tas T)
    {
      while(T->dernier >= T->taille_physique)
        T->taille_physique += BLOC;
      realloc(T->arbreBinaire, T->taille_physique *sizeof(T->arbreBinaire));
    }
    Tu ne récupères pas l'adresse renvoyée par realloc.

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 12
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    Tu ne récupères pas l'adresse renvoyée par realloc.

    Merci, c'était cette erreur qui faisait la bazar, je me demande encore pour Linux ne me detecte pas d'erreur ?

  10. #10
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    C'est pas qu'il ne détecte pas c'est qu'à mon avis par "malchance" il ne modifiait pas l'adresse d'origine donc ça restait cohérent.

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mommsse Voir le message
    C'est vrai, ce n'est pas une erreur de compilation mais bien d'execution, mais ce que je n'arrive pas à comprendre, c'est que lorsque je debug avec gdb, l'erreur survient 2 fois, et jamais lorsque je libere la memoire ...
    .....
    J'arrive vraiment pas a comprendre d'ou ca vient ??
    Citation Envoyé par mommsse Voir le message
    J'ai détecté l'erreur mais je ne la comprend pas:
    ....
    Et pourquoi cela ne survient-il que sous Leopard et pas sous Linux ?
    Nous ne le répéterons jamais assez : un comportement indéterminé et fluctuant, un crash en ajoutant ou enlevant une ligne ou un caractère, un crash sur un système et pas sur un autre, au runtime est CERTAINEMENT dû à un problème de mémoire.

    Donc, dès qu'il apparaît ce genre de problèmes, se pencher tout de suite sur ses tableaux et allocations....


    Citation Envoyé par nicolas.sitbon Voir le message
    C'est pas qu'il ne détecte pas c'est qu'à mon avis par "malchance" il ne modifiait pas l'adresse d'origine donc ça restait cohérent.
    c'est pas de la "malchance"....

    En entrée, tu as un pointeur..

    Vu que la sortie est omise, l'adresse d"origine n'est JAMAIS modifiée....


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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    c'est pas de la "malchance"....

    En entrée, tu as un pointeur..

    Vu que la sortie est omise, l'adresse d"origine n'est JAMAIS modifiée....
    Ca c'est clair. La malchance, c'est que l'adresse reste apparemment valide sous Linux, d'où l'absence de comportement erroné visible...

  13. #13
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Ca c'est clair. La malchance, c'est que l'adresse reste apparemment valide sous Linux, d'où l'absence de comportement erroné visible...
    vi, mais je pense que c'est logique : le programme est en memoire, avec sa plage d'adresses...
    Vu que le PO faisait un realloc, au meme endroit, avec une taille de plus en plus grande, il n'y avait pas de raisons que la premiere adresse ne soit plus valable.. et ce meme si il deplacait le tableau, tant qu'il n'y a pas d'allocations entre temps...

    Enfin tout ceci ne serait pas arrive si le compilo etait bien regle

    "no return value in a function with a non-void type"....

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    vi, mais je pense que c'est logique : le programme est en memoire, avec sa plage d'adresses...
    Vu que le PO faisait un realloc, au meme endroit, avec une taille de plus en plus grande, il n'y avait pas de raisons que la premiere adresse ne soit plus valable.. et ce meme si il deplacait le tableau, tant qu'il n'y a pas d'allocations entre temps...
    Bah, quand on agrandit un tableau il est plus que probable que l'adresse du bloc change un jour ou l'autre. C'est quand on le rétrécit que c'est plus rare...
    Enfin tout ceci ne serait pas arrive si le compilo etait bien regle

    "no return value in a function with a non-void type"....
    Bah non. Ce warning évite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    int f(void)
    {
        /* ... */
     
       /* manque un return xxx; */
    }

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    ah desole j'avais pas vu qu'il l'avait defini comme void...

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mommsse Voir le message
    Merci, c'était cette erreur qui faisait la bazar,
    Et je te conseille de traiter le problème correctement :

    http://emmanuel-delahaye.developpez....es.htm#realloc

Discussions similaires

  1. Erreur de compilation après modification du Uses
    Par DevelOpeR13 dans le forum Langage
    Réponses: 5
    Dernier message: 30/10/2007, 14h23
  2. Réponses: 2
    Dernier message: 23/09/2003, 14h32
  3. Réponses: 10
    Dernier message: 22/09/2003, 21h58
  4. Réponses: 4
    Dernier message: 27/08/2003, 21h34
  5. Réponses: 2
    Dernier message: 04/03/2003, 23h24

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