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 :

Encore un probleme de Liste chainée


Sujet :

C

  1. #1
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut Encore un probleme de Liste chainée
    Bon salut les gars,
    Je développe actuellement un client xHextris version multijoueur. Pour résumer,
    mon programme recoit en paramètre :
    - a : pour spécifier que le jeu se lance en mode automatique
    - b : pour spécifier la couleur de fond
    - sinon une liste d'adresse IP qui correspondront aux @ des joueurs connectés.

    J'utilise une liste chainée pour enregistrer la liste des joueurs. Mais j'ai des comportements bizarres avec ma liste. Qd je lui passe mes @IP (par ex 3), il y'a une @ "fictive" ou zombie, qui est rajouté dans la liste et je ne sais pas d'où il sort.
    Un exemple d'exécution :
    lindows@lindows-desktop:~/xhextris$ ./xhextris -a -b yellow 140.33.45.2 134.12.25.25 136.12.123.0
    xhextris number 67108865
    Initialisation des resources couleurs.....OK
    Background = yellow
    NULL NULL
    Insertion de 140.33.45.2 à 4
    Insertion de 134.12.25.25 à 5
    Insertion de 136.12.123.0 à 6
    Liste des joueurs connectés
    @IP : 136.12.123.0
    @IP : 134.12.25.25
    @IP : 140.33.45.2
    @IP : 49.48.48.100
    Erreur de segmentation
    Comme vous le voyez ici, je lui passe 3 @IP en paramètre, et qd je lui demande d'afficher ma liste il m'en sort 4. . J'ai regardé du coté des fonctions d'insertion de ma liste chainée, tout semble correct. Je vous laisse mon code et je vous remercie pour votre aide.

    Ma Structure pour stocker mes joueurs :
    Code C : 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
     
    /* Definition de la liste des joueurs. */
     
    typedef struct _un_joueur {
     int score;
     struct sockaddr_in adresse_ip;
    } Un_joueur;
     
     
    typedef struct _liste_joueur * P_liste_joueur;
     
    typedef struct _liste_joueur {
      Un_joueur joueur;  
      P_liste_joueur next;
    } Liste_Joueur;
     
     
     
    P_liste_joueur init_liste(char *liste[], int debut,int nb_joueur);
    P_liste_joueur int_joueur (char *adresse_ip);
    void display_liste_joueurs (P_liste_joueur l);

    Mes fonctions de gestion de la liste :
    Code C : 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
     
    #include "xhextris.h"
     
    P_liste_joueur init_joueur (char* adresse_ip){
     P_liste_joueur el = (P_liste_joueur) malloc(sizeof(Liste_Joueur));
     Un_joueur j = { 0, 
    		 {AF_INET, htons(PORT), {inet_addr(adresse_ip)}} 
    	       };
     
     if(!el) return NULL;
     
     el -> joueur = j;
     el -> next = NULL;
     
     return el;
    }
     
     
    P_liste_joueur init_liste(char *liste[], int debut,int nb_joueur){
     P_liste_joueur el, l;
     int i;
     char *addr;
     
     l = (P_liste_joueur) malloc(sizeof(Liste_Joueur)* (nb_joueur - debut));
     
     for(i = debut ; i < nb_joueur; i++){
       addr = liste[i];   
       fprintf(stdout,"Insertion de %s à %d\n", addr,i);
       el = init_joueur (addr);
       l = inserer_joueur (l, el);
     }
     
     return l;
    }
     
     
    P_liste_joueur inserer_joueur(P_liste_joueur maliste, P_liste_joueur joueur){
     joueur -> next  = maliste;
     return joueur;
    }
     
    void display_liste_joueurs(P_liste_joueur l){
     P_liste_joueur deb = l;
     Un_joueur j;
     fprintf(stdout, "Liste des joueurs connectés\n");
     while(deb -> next != NULL){
      j = deb -> joueur;
      fprintf(stdout,"@IP : %s\n", inet_ntoa(j.adresse_ip.sin_addr));
      deb = deb -> next;
     }
     
    }

    Merci pour votre aide !!

  2. #2
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut
    Quand j'utilise valgrind pour pour débugger mon programme, tout marche nickel :
    Exemple :
    lindows@lindows-desktop:~/Bureau/xhextris$ valgrind --tool=memcheck --leak-check=full --show-reachable=yes --leak-resolution=high ./xhextris -a -b yellow 127.3.25.3 140.33.45.2 134.12.25.254
    Affichage
    ........
    xhextris number 67108865
    Initialisation des resources couleurs.....OK
    Background = yellow
    Insertion de 127.3.25.3 à 4
    Insertion de 140.33.45.2 à 5
    Insertion de 134.12.25.254 à 6
    Liste des joueurs connectés
    @IP : 134.12.25.254
    @IP : 140.33.45.2
    @IP : 127.3.25.3
    .........

  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
    Il y a des choses bizarres :
    init_liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     l = (P_liste_joueur) malloc(sizeof(Liste_Joueur)* (nb_joueur - debut));
    ceci ne crée pas une liste mais un tableau de (nb_joueur - debut) Liste_Joueur (mais alors, pourquoi avoir le champ next). On peut s'attendre à ce que les joueurs soient placés dans ce tableau. Et ce n'est pas le cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     el = init_joueur (addr);
     l = inserer_joueur (l, el);
    Tu utilises l comme si tu avais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     l =  malloc(sizeof(Liste_Joueur));
    Toutefois, ceci crée un élément Liste_Joueur non initialisé, en particulier son champ next (cet élément n'est pas utilisé). Comme tu insères en tête de la liste, le dernier élément (qui est celui dont on parle ci-dessus) a un champ next qui vaut ????

    Lors de l'affichage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ....
     while(deb -> next != NULL){
      j = deb -> joueur;
      fprintf(stdout,"@IP : %s\n", inet_ntoa(j.adresse_ip.sin_addr));
      deb = deb -> next;
     }
    le test deb -> next != NULL peut alors être vrai sur le dernier élément de la liste et tu continues en affichant n'importe quoi.

  4. #4
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut
    EN fait ma liste je l'initialise dans mon programme principal en appelant la fonction
    init_liste. Merci pour ton aide, je vais y jeter un coup d'oeil. C'est vrai que ce malloc est bizarre mais je ne me rappelle plus pourquoi je l'ai fait.

    Je te tiens au courant !!

  5. #5
    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
    EN fait ma liste je l'initialise dans mon programme principal en appelant la fonction init_liste.
    init_liste n'initialise PAS le champ next à NULL du (des) Liste_Joueur créé(s) par le malloc

  6. #6
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par diogene Voir le message
    init_liste n'initialise PAS le champ next à NULL du (des) Liste_Joueur créé(s) par le malloc
    Ca je sais. C'est une liste que j'alloue et que je vais remplir à chaque tour de boucle un joueur. Je ne vois pas en quoi le malloc gène l'initialisation de ma liste

  7. #7
    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
    Ca je sais. C'est une liste que j'alloue et que je vais remplir à chaque tour de boucle un joueur. Je ne vois pas en quoi le malloc gène l'initialisation de ma liste
    Sauf erreur de ma part, tu ne remplis PAS le premier élément (celui créé avec le premier malloc) de ta liste par un joueur et il reste inoccupé. Ce n'est pas grave, sauf que cet élément ne termine pas correctement la liste puisque son pointeur next n'est pas mis à NULL.

    init_liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l =  malloc(sizeof(Liste_Joueur));
    l->next = NULL;

  8. #8
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par publicStaticVoidMain Voir le message
    Quand j'utilise valgrind pour pour débugger mon programme, tout marche nickel :
    typique d'un problème mémoire

    comportement non consistant..

  9. #9
    Membre confirmé

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Août 2007
    Messages
    509
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Août 2007
    Messages : 509
    Points : 622
    Points
    622
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     l = (P_liste_joueur) malloc(sizeof(Liste_Joueur)* (nb_joueur - debut));
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     l =  malloc(sizeof(Liste_Joueur));
    Merci pour ton conseil, t'as en effet raison. Je viens de vérifier et ca marche. Je ne sais meme pas pourquoi j'ai fait ça.
    C'est résolu

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

Discussions similaires

  1. encore un probleme de liste déroulante
    Par popofpopof dans le forum IHM
    Réponses: 4
    Dernier message: 29/08/2008, 21h09
  2. Probleme avec liste chainée
    Par Lucas42 dans le forum C
    Réponses: 3
    Dernier message: 20/11/2007, 19h46
  3. probleme avec liste chainée
    Par isoman dans le forum C
    Réponses: 14
    Dernier message: 29/11/2006, 23h03
  4. probleme avec liste chainée
    Par Liiscar dans le forum Collection et Stream
    Réponses: 3
    Dernier message: 28/11/2006, 20h37
  5. Probleme arbre/liste chainée en template
    Par Raton dans le forum Langage
    Réponses: 1
    Dernier message: 07/11/2005, 16h09

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