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 :

[C] Liste Chaînée, prob avec le premier element


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Développeur .NET
    Inscrit en
    Février 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2006
    Messages : 107
    Par défaut [C] Liste Chaînée, prob avec le premier element
    Bonjour,
    J'ai un projet a rendre pour dans...bientot et j'ai toujours un probleme avec mon programme...

    En effet, lors de ma premiere insertion, il y a un bug qui n'insere rien dans le premier element, donc rien dans les suivants bug avec memoire x232 ne peut pas etre written dans 0x00 ou un truc du genre...pourquoi? et comment y remédier?

    Une précision, ce programme devra tourner sous linux et je ne peux pas modifier mes typedef et mes parametre (donc je ne peux pas faire )
    Je vous remercie d'avance pour le temps que vous prenez a étudier mon probleme.

    P.S : je sais qu'il y a plein de tutoriaux, faqs etc...mais pour le moment je n'ai pas trouvé la solution.

    Voici ce que j'ai en gros :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct noeud * Noeud;
    typedef struct noeud {
            int n;
            Noeud suivant;
            } * Liste;
    main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Liste l = NULL;
    test = inserer(l, val);
    inserer :
    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
    int inserer(Liste l, int x)
    {
        int test = 0;
        Liste lBis = (Liste) malloc (sizeof(struct noeud));
        Liste l2 = (Liste) malloc (sizeof(struct noeud));
        if(l == NULL)//si la chaine est vide
             {
                  l = (Liste) malloc (sizeof(struct noeud));
                  (*l).n = x;//on met la valeur au noeud
                  (*l).suivant = NULL;//on indique que le suivant est null
                  test = 1;
             }
        else
        {
            lBis = l; 
            while(test == 0)//si la chaine (1er noeud n'est pas null) a été créée
            {
                 if((*lBis).suivant == NULL)//s'il n'y a pas de valeur apres celui de l'insertion
                 {                       
                      (*l2).n = x;//on peut alors ajouter la valeur demandé
                      (*l2).suivant = NULL;//le suivant est donc null
                      (*lBis).suivant = l2;//on met le lien entre l'avant dernier et le dernier
                      test = 1;
                 }
                else    
                      lBis =  (*lBis).suivant;  
           }
        }
        free(lBis);
        free(l2);
        return test;
    }

  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 gusrom86
    Une précision, <...> et je ne peux pas modifier mes typedef et mes parametre (donc je ne peux pas faire )
    Ah ? Alors à ma connaissance, pas de solution.

  3. #3
    Membre confirmé
    Profil pro
    Développeur .NET
    Inscrit en
    Février 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2006
    Messages : 107
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Ah ? Alors à ma connaissance, pas de solution.
    Si j'avais pu le faire, tu peux me donner ce qui l'aurait réglé?

  4. #4
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Pourquoi enlever les typedef je ne comprends pas
    Le code donné dans le main n'alloue qu'un seul noeud

  5. #5
    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 gusrom86
    Si j'avais pu le faire, tu peux me donner ce qui l'aurait réglé?
    Si tu veux qu'un fonction modifie une variable, il n'y a que 2 solutions :

    Passer son adresse via un pointeur du même type :
    Utiliser la valeur retournée pour modifier la variable :
    Le fait que la variable soit un pointeur ne change rien à cette problématique.

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 194
    Par défaut
    dans ta fonction inserer, il ne faut pas liberer la mémoire alloué auparavant.
    tu crée un élément et tu l'effaces juste après.
    par contre tu devrais écrire une fonction que tu appellerais vers la fin pour libérer la mémoire occupé par la liste chaînée.
    ensuite comme l'a indiqué Emmanuel Delahaye, il te faut passer l'adresse du pointeur vers le premier noeud, sinon si il est null, il ne sera pas modifié et donc ton premier noeud ne sera pas ajouté.

  7. #7
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Quelques remarques sur le code....


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct noeud * Noeud;
    typedef struct noeud {
            int n;
            Noeud suivant;
            } * Liste;
    On ne cache pas les pointeurs, c'est une mauvaise habitude ou alors on met dans le nom du typedef un identificateur pour savoir que c'est un pointeur.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct noeud * Noeud;
    typedef struct noeud {
            int n;
            Noeud suivant;
            } * P_Liste; /* P pour dire pointeur */

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int inserer(Liste l, int x)
    {
        int test = 0;
        Liste lBis = (Liste) malloc (sizeof(struct noeud));
        Liste l2 = (Liste) malloc (sizeof(struct noeud));
    - lBis ne sert à rien, n'est pas alloué pour une raison valable puisque tu écrases sa valeur avec l dans le cas else. Tu fais ensuite un free sur un élément qui n'est pas forcément celui qui est alloué!!

    - On ne cast pas le retour de malloc et on ne fait pas de sizeof du type, cela nuit à la portabilité. On test aussi le retour de malloc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        P_Liste l2 = malloc (sizeof(*P_Liste));
     
        if(l2 == NULL) {
                /* Gestion de l'erreur */
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
                  l = (Liste) malloc (sizeof(struct noeud));
                  (*l).n = x;//on met la valeur au noeud
                  (*l).suivant = NULL;//on indique que le suivant est null
    Malloc à changer et pourquoi s'embêter dans la suite ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
                  l = malloc (sizeof(*l));
     
                  if(l==NULL) {
                          /* Gestion de l'erreur */
                  }
                  l->n = x;//on met la valeur au noeud
                  l->suivant = NULL;//on indique que le suivant est null
    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
     
        else
        {
            lBis = l; 
            while(test == 0)//si la chaine (1er noeud n'est pas null) a été créée
            {
                 if((*lBis).suivant == NULL)//s'il n'y a pas de valeur apres celui de l'insertion
                 {                       
                      (*l2).n = x;//on peut alors ajouter la valeur demandé
                      (*l2).suivant = NULL;//le suivant est donc null
                      (*lBis).suivant = l2;//on met le lien entre l'avant dernier et le dernier
                      test = 1;
                 }
                else    
                      lBis =  (*lBis).suivant;  
           }
        }
    }
    Pourquoi chercher midi à 14h dans ton else ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        else
        {
            lBis = l; 
            while(lBis -> suivant != NULL) //si la chaine (1er noeud n'est pas null) a été créée
            {
                 lBis = lBis->suivant;
            }
     
             l2->n = x;//on peut alors ajouter la valeur demandé
             l2->suivant = NULL;//le suivant est donc null
             lBis->suivant = l2;//on met le lien entre l'avant dernier et le dernier
          }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        free(lBis);
        free(l2);
        return test;
    - Pas de free pour lBis puisque j'ai enlevé l'allocation de lBis
    - Faire un free de l2 n'a aucun sens puisque tu veux garder ce nouveau élément dans ta chaîne pas le perdre
    - Le return test retournait toujours 1, pourquoi le faire sauf dans le cas où on dit que si on a une allocation qui plante, on retourne 0 mais à ce moment là, on a simplement un return 1.

    Enfin et bien sûr cette fonction ne fera pas son travail correctement tant que tu ne décideras pas entre les deux versions que te propose Emmanuel qui sont les seules solutions pour faire que cette fonction fonctionne

    Je te laisse adapter le code,

    Jc

Discussions similaires

  1. Réponses: 6
    Dernier message: 05/01/2011, 14h42
  2. Réponses: 9
    Dernier message: 14/01/2007, 17h09
  3. Quicksort avec listes chaînées ?
    Par italiasky dans le forum C
    Réponses: 3
    Dernier message: 27/12/2006, 16h47
  4. [TP 7] Problème avec les listes chaînées (error 202)
    Par thelinekioubeur dans le forum Turbo Pascal
    Réponses: 4
    Dernier message: 06/12/2006, 23h15
  5. [AJAX] listes dynamiques liées a la premiere avec XMLhttpRequest
    Par metatron dans le forum Général JavaScript
    Réponses: 33
    Dernier message: 09/10/2006, 09h30

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