Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème étrange Liste génériques(sur des entiers)

Sujet résolu
    16 novembre 2018 à 21:17:48

    Bonjour 

    Essayant de créer une bibliothèque de listes génériques et de la tester sur des entiers je l'ai code (évidemment) mais un comportement étrange auquel j'ai pas trouve d'explication me bloque :

    En compilant (Malheureusement ca ne donne pas d'erreurs) et testant je me rend compte que chaque valeur de la variable temp devient automatiquement le contenu de tout les élement de la liste .

    J'ai memeajouter un (une) case ou l'utilisateur entre une valeur et aprés j'affiche le contenu de la liste deja remplie préalablement (je ne voit pas la relation entre eux dans ce cas) mais magiquement tout les élements de la liste devient égal a temp.

    Voici le fichier liste.h :

    typedef int  booleen;
    typedef void Objet;
    
    #define NONORDONNE  0
    #define CROISSANT   1
    #define DECROISSANT 2
    
    // un élément de la liste
    typedef struct element {
      Objet*          reference;
      struct element* suivant;
    } Element;
    
    // le type Liste
    typedef struct {
      Element* premier;
      Element* dernier;
      Element* courant;
      int      nbElt;
      int      type;    // 0:simple, 1:croissant, 2:décroissant
      char*    (*afficher) (Objet*);
      int      (*comparer) (Objet*, Objet*);
    } Liste;
    
    void     initListe              (Liste* li, int type, char* (*afficher) (Objet*), int (*comparer) (Objet*, Objet*) );
    Liste*   creerListe             (int type, char* (*afficher) (Objet*), int (*comparer) (Objet*, Objet*) );
    
    booleen  listeVide              (Liste* li);
    int      nbElement              (Liste* li);
    
    void     insererEnTeteDeListe   (Liste* li, Objet* objet);
    void     insererEnFinDeListe    (Liste* li, Objet* objet);
    
    void     listerListe            (Liste* li);
    
    
    
    

    liste.c :

    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #include "liste.h"
    
    Liste*  creerListe (int type, char* (*afficher) (Objet*), int (*comparer) (Objet*, Objet*) )
    {
        Liste* li=(Liste*)malloc(sizeof(Liste));
        initListe (li,0, NULL, NULL);
        return li;
    }
    void initListe (Liste* li, int type, char* (*afficher) (Objet*), int (*comparer) (Objet*, Objet*) )
    {
        li->type=type;
        li->afficher=afficher;
        li->comparer=comparer;
        li->courant=NULL;
        li->premier=NULL;
        li->dernier=NULL;
        li->nbElt=0;
    }
    int nbElement (Liste* li)
    {
        return (li->nbElt);
    }
    int  listeVide (Liste* li)
    {
        return ( (li->nbElt) ==0);
    }
    Element* creeElement()
    {
        Element* el=(Element*)malloc(sizeof(Element));
        return el;
    }
    void insererEnTeteDeListe  (Liste* li, Objet* objet)
    {
        Element* el=creeElement();
        el->reference=objet;
        el->suivant=li->premier;
        li->premier=el;
        if(listeVide(li))
            li->dernier=el;
        li->nbElt++;
    }
    void insererEnFinDeListe (Liste* li, Objet* objet)
    {
        if(listeVide(li))
        {
            insererEnTeteDeListe  (li,objet);
            return;
        }
        Element* el=creeElement();
        el->reference=objet;
        el->suivant=NULL;
        li->dernier->suivant=el;
        li->dernier=el;
        li->nbElt++;
    }
    void listerListe (Liste* li)
    {
        Element* tempo=li->premier;
        while(tempo != NULL)
        {
            printf("%s ",li->afficher(tempo->reference));
            tempo = tempo -> suivant;
        }
    }
    
    
    

    mainliste.c :

    #include <stdio.h>
    #include <stdlib.h>
    #include<string.h>
    #include "liste.h"
    
    int menu()
    {
        printf("\n\nGESTION D'UNE LISTE D'ENTIERS \n\n");
    
        printf("1-Initialiser une liste\n");
        printf("2-Retourner le nombre des objets\n");
        printf("3-Verifier si la liste est vide\n");
        printf("4-Insertion en tete de liste\n");
        printf("5-Insertion fin de liste\n");
        printf("6-Afficher les objets de la liste\n");
        printf("7-Fin\n");
        printf("0-test ");
    
        printf("\n");
        printf("Votre choix ?");
        int cod;scanf("%d",&cod);getchar();
        printf("\n");
        return cod;
    }
    char* afficher_entier(Objet* objet)
    {
        char* output = (char*)malloc(sizeof(int));
        snprintf(output,sizeof(int),"%d",*((int*)objet));
        return output;
    }
    int comparer_entier(Objet* e1,Objet* e2)
    {
        char* i1=(char*)e1;
        char* i2=(char*)e2;
        return strcmp(i1,i2);
    }
    int main (void)
    {
        int temp;
        int choix;
        Liste* li=(Liste*)malloc(sizeof(Liste));
        li=creerListe  (0,afficher_entier,comparer_entier);
        do{
            choix=menu();
            switch (choix) {
            case 1 : {initListe (li,0, afficher_entier,comparer_entier);
                        printf("La liste a ete initialisee");
                        }
                        break;
            case 2 : printf("Le nombre des elements est : %d",nbElement (li));
                        break;
            case 3 :{if(listeVide(li))
                            printf("La liste est vide");
                        else
                            printf("La liste contient des elements");
                        }
                        break;
            case 4 : {printf("Quelle element voulez-vous inserer => ");
                        scanf("%d",&temp);
                        insererEnTeteDeListe(li,&temp);
                        }
                        break;
            case 5 : {printf("Quelle element voulez-vous inserer => ");
                        scanf("%d",&temp);
                        insererEnFinDeListe(li,&temp);
                        listerListe(li);
                        }
                        break;
            case 6 : listerListe(li);
                        break;
            case 7 : break;
            case 0 : {printf("entrez un element :");
                            scanf("%d",&temp);
                            listerListe(li);}
                            break;
            }
        }while(choix!=7);
    
    }
    
    

    Merci de me pointer mes erreurs. 



    -
    Edité par Hich@m 16 novembre 2018 à 21:29:17

    • Partager sur Facebook
    • Partager sur Twitter
      16 novembre 2018 à 23:10:40

      Hello,

      Hich@m a écrit:

      je me rend compte que chaque valeur de la variable temp devient automatiquement le contenu de tout les élement de la liste

      Normal: ta variable reference (pointeur) reçoit l'adresse de la variable temp que tu as scanf() dans le main(). Or, à chaque scanf(), si temp change de valeur, elle ne change pas d'adresse.

      Donc toutes les variables reference de ta liste pointant vers temp, elles ne peuvent qu'afficher une seule et même valeur: la dernière donnée à temp.

      Edit: je n'ai pas cherché d'autre problème dans ton code.



      -
      Edité par edgarjacobs 16 novembre 2018 à 23:18:53

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        17 novembre 2018 à 13:22:28

        Donc pour résoudre ce problème il faut ajouter une fonction qui me fournit à chaque fois un emplacement différent (en utilisant malloc) .

        Merci beaucoup Mr edgarjacobs  (j'avoue je suis déçu d'avoir laissé passer une telle erreur) . 

        • Partager sur Facebook
        • Partager sur Twitter
          18 novembre 2018 à 16:00:37

          Si ça peut te rassurer il y a un certain nombre d'autres erreurs.
          Par exemple :
          fonction afficher_entier() l'allocation n'est pas du tout de la bonne taille, et la libération n'est effectuée nulle part (memory leak).
          fonction comparer_entier() : présuppose que les données sont des chaînes, pas des entiers. Ça risque de faire des étincelles.
          • Partager sur Facebook
          • Partager sur Twitter

          En recherche d'emploi.

          Problème étrange Liste génériques(sur des entiers)

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown