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 :

structures recursives et pointeurs!


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut structures recursives et pointeurs!
    Bonjour tout le monde,

    Je suis des cours de C à la fac, que j'ai déjà eu dans mes années antérieures, et du coup en cours je m'amuse à me faire une toute petite bibliothèque des listes l'histoire que je me rappelle des principes fondamentaux du C.

    Vu que je sais que je n'arriverais pas verbalement à expliciter mon problème je vous donnes les parties de sources qui me posent problèmes.

    Tout d'abord voici comment je définis mes structures :
    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
     
    typedef int coeff;
     
    typedef struct entite
    {
      struct entite *prec;
      struct entite *succ;
      coeff valeur;
    } entite;
     
    typedef struct liste
    {
      entite *premier;
      entite *dernier;
      unsigned short taille;
    } liste;

    Et maintenant dans une de mes fonctions lorsque j'execute mon programme ( car oui il compile avec gcc -W -Wall -pedantic -ansi ), j'ai une erreur de segmentation à cette ligne ci du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    liste *l;
    entite *ajout;
     
    if((ajout = (entite*) malloc(sizeof(entite))) == NULL)
      {
        printf("Erreur : allocation memoire impossible.\n");
      }
    /*Aucun message d'erreur n'apparait*/
     
     
    (l->premier)->prec = ajout; /*c'est cette ligne qui me fait mon erreur de segmentation*/
    merci d'avance de vos suggestions de débogages. Car personnelement je ne vois pas où cherchais mon information de debogage mis à part à demander à une population d'expert ;-)

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

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Ton pointeur liste*l ne pointe sur rien.
    Cordialement.

  3. #3
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    As-tu alloué la mémoire pour ta liste l (cet identificateur n'est pas très bien choisi, car on le confond facilement avec le chiffre 1)? Par ailleurs, si la mémoire pour l a bien été a bien été allouée mais que la liste est vide, l->premier vaut sans doute NULL. Par conséquent, l->premier->prec entraine une erreur de segmentation, car tu déréférence un pointeur NULL.

    En résumé, il faut:
    • être certain que la mémoire pour le pointeur l a été allouée
    • gérer correctement le cas où la liste est vide


    Pour ajouter un élément en tête de liste, je ferais:

    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
    int liste_ajouter_en_tete(list *self, coeff val)
    {
        int err = 0;
     
        if (p_self != NULL)
        {
            entite *p_ajout = NULL;
     
            p_ajout = malloc(sizeof *p_ajout);
            if (p_ajout != NULL)
            {
                /*-tc- initialisation des champs de p_ajout */
                static entite tmp = {0};
                *p_ajout = tmp;
                p_ajout->valeur = val;
     
                if (self->premier == NULL)
                {
                    self->premier = p_ajout;
                    self->dernier = p_ajout;
                }
                else
                {
                    self->premier->prec = p_ajout;
                    p_ajout->succ = self->premier;
                    self->premier = p_ajout;
                }
            }
            else
            {
                err = 2;
                fprintf(stderr, "Erreur: allocation mémoire impossible.\n");
            }
        }
        else
        {
            err = 1;
            fprintf(stderr, "Erreur: l'argument self doit être non NULL.\n");
        }
        return err;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    Autant pour moi j'ai trouvé le probleme!!

    Tout d'abord je tiens à vous remercier de vos réponses.


    Le problème consister lorsque ma liste était vide est du coup

    pointé vers NULL... ca se voit que ca fait lontemps que je n'ai pas fait du C

    En tout cas merci beaucoup vos reponses.

    A bientôt pour des nouvelles aventures!!!

    (Au passage Thierry chapuis avait trouvé la reponse!! je m'incline)

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    De plus: Tu peux supprimer le cast du retour de malloc(). Il est inutile en C et même déconseillé.
    Le cast des pointeurs void* n'est nécessaire qu'en C++.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    oki merki de la precision, mais si je ne me trompe pas je crois que c'est l'un des grands débats des developpeur en C de caster le malloc non?

    Personnelement je n'ai pas assez de connaissance pour prendre un parti ou l'autre, mais seulement que tous mes profs de C que j'ai pu avoir qui se reduit a 3 le cast donc au final je fais comme eux!!! ( la theorie des moutons panurge!!)

    D'ailleur sans vouloir ouvrir de polemiques quels sont les arguments pour caster ou pas le malloc c'est un debat dont je ne connais pas vraiment les arguments

    merci d'avance

  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 barbsbou Voir le message
    oki merki de la precision, mais si je ne me trompe pas je crois que c'est l'un des grands débats des developpeur en C de caster le malloc non?
    Y'a pas de débat. Le cast est inutile. Point.

    http://emmanuel-delahaye.developpez....tes.htm#malloc

    Même Brian Kernighan a fini par l'admettre dans l'errata du K&R2 (#142)

    http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par barbsbou Voir le message
    D'ailleurs sans vouloir ouvrir de polemiques quels sont les arguments pour caster ou pas le malloc c'est un debat dont je ne connais pas vraiment les arguments
    Première chose, ce caste est inutile, donc autant éviter dans ce cas de taper du code pour rien. Deuxièmement, le cast peut inhiber la possibilité pour le compilateur de signaler une erreur lorsque l'inclusion de stdlib.h est omise. Effet, dans ce cas, le compilateur admet que malloc() renvoie une valeur de type int. Comme la conversion implicite de int vers n'importe quel pointeur n'est pas autorisée... le compilateur peut signaler l'erreur.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Et j'ai deux exemples concrets où le cast est vraiment nuisible si tu oublies de déclarer malloc() (en incluant <stdlib.h>) :
    • Windows 64 bits : un int fait 32 bits, un pointeur 64 bits. Si le compilo croit que malloc() retourne un int, il perdra la moitié des bits du pointeur.
    • Calculatrice TI-89 : Les entiers ne sont pas retournés par le même registre que les pointeurs (D0 pour les entiers, A0 pour les pointeurs).
      • Et par extension, sûrement d'autres systèmes utilisant un Microprocesseur 68000 ou dérivé.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 67
    Par défaut
    Je vous remercie de vos reponses, j'y voit un peu plus clair sur cette question qui apriori n'est pas un débat!!

    ( en meme temps il y a quelques années tout le monde n'était pas aussi categorique sur le sujet!!)

    Mais malheureusement vu que les personnes qui me notes veulent qu'on cast alors je m'y plirais mais au fond je sait qu'il faut pas oublier le stdlib.h ;-)

    Encore merci!

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Donne à ces personnes un lien vers ici, ainsi que le lien vers l'errata du K&R2.
    Si elles persitent à exiger un cast, fais-les virer ou change d'établissement.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

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

Discussions similaires

  1. Réponses: 6
    Dernier message: 12/09/2007, 15h58
  2. Réponses: 9
    Dernier message: 14/01/2007, 16h40
  3. Structure, union et pointeur
    Par kikoo.plop dans le forum C
    Réponses: 10
    Dernier message: 18/12/2006, 19h21
  4. structure, tableau et pointeur
    Par Phil' dans le forum GTK+ avec C & C++
    Réponses: 16
    Dernier message: 26/05/2006, 17h47
  5. structure recursive et fichier
    Par KrusK dans le forum C
    Réponses: 4
    Dernier message: 04/01/2006, 13h08

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