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

Linux Discussion :

Besoin d'aide listes chainées


Sujet :

Linux

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut Besoin d'aide listes chainées
    Bonjour à tous,

    Je suis étudiant en informatique et je programme un projet en C norme POSIX sous FreeBSD (j'ai pas la version en tête).

    Tout allait bien avec mes listes chainées jusqu'à ce que je fasse mumuse avec.
    Et la Valgrind est devenu tout rouge et à commencé à m'insulter, moi, pauvre petit étudiant pas toujours studieux mais de bonne volonté !

    Je ne vais pas mettre toutes les erreurs qu'il m'a mis mais voici un condensé :

    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
    ==64910== Use of uninitialised value of size 4
    ==64910==    at 0x8049D2C: rebuild (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x8049E87: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804946F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x80494F9: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910== 
    ==64910== Invalid read of size 4
    ==64910==    at 0x8049D2C: rebuild (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x8049E87: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804946F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x80494F9: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==  Address 0x3C15942C is 16 bytes inside a block of size 20 free'd
    ==64910==    at 0x3C034687: free (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
    ==64910==    by 0x804B18D: xfree (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x8049E7C: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804946F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910== 
    ==64910== Conditional jump or move depends on uninitialised value(s)
    ==64910==    at 0x8049475: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x80494F9: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804A280: main (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    Les autres sont les même mais repérées ailleurs pas valgrind je crois.

    J'ai donc regardé, et j'ai vu qu'une grosse part de mes problêmes semblaient resider dans ce genre de tests : if (elem).
    "elem" étant un élément d'un liste chainée.

    Je voudrais donc savoir comment protéger mes fonctions en testant si mes maillons ne sont pas égaux à 0 mais sans avoir ces erreurs.

    Merci d'avance,

    Nyro.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nyromancer Voir le message
    Bonjour à tous,

    Je suis étudiant en informatique et je programme un projet en C norme POSIX sous FreeBSD (j'ai pas la version en tête).

    Tout allait bien avec mes listes chainées jusqu'à ce que je fasse mumuse avec.
    Et la Valgrind est devenu tout rouge et à commencé à m'insulter, moi, pauvre petit étudiant pas toujours studieux mais de bonne volonté !

    Je ne vais pas mettre toutes les erreurs qu'il m'a mis mais voici un condensé :

    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
    ==64910== Use of uninitialised value of size 4
    ==64910==    at 0x8049D2C: rebuild (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x8049E87: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804946F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x80494F9: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910== 
    ==64910== Invalid read of size 4
    ==64910==    at 0x8049D2C: rebuild (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x8049E87: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804946F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x80494F9: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==  Address 0x3C15942C is 16 bytes inside a block of size 20 free'd
    ==64910==    at 0x3C034687: free (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
    ==64910==    by 0x804B18D: xfree (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x8049E7C: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804946F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910== 
    ==64910== Conditional jump or move depends on uninitialised value(s)
    ==64910==    at 0x8049475: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x80494F9: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==64910==    by 0x804A280: main (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    Les autres sont les même mais repérées ailleurs pas valgrind je crois.

    J'ai donc regardé, et j'ai vu qu'une grosse part de mes problêmes semblaient resider dans ce genre de tests : if (elem).
    "elem" étant un élément d'un liste chainée.

    Je voudrais donc savoir comment protéger mes fonctions en testant si mes maillons ne sont pas égaux à 0 mais sans avoir ces erreurs.

    Merci d'avance,

    Nyro.
    Mouais. Plein de bonnes volonté mais pas très au point quoi. Parce que sans les sources, ça va être dur de t'aider. Et ta question peut se résumer en "comment bien programmer". Et la réponse se résumera en "ben en bien programmant".

    Déjà un maillon d'une liste ne peut pas être égal à 0 car le test est sensé avoir été fait lorsque le maillon a été créé et s'il était à 0 à ce moment là, il est sensé ne pas avoir été inséré dans la liste.

    Pour le reste, je ne peux que te renvoyer sur ce tuto qui traite des listes chainées => http://nicolasj.developpez.com/articles/listesimple/
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 579
    Points
    218 579
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Mouais. Plein de bonnes volonté mais pas très au point quoi. Parce que sans les sources, ça va être dur de t'aider. Et ta question peut se résumer en "comment bien programmer". Et la réponse se résumera en "ben en bien programmant".
    Et moi qui ai casse ma boule de crystal l'annee derniere

    Sinon voici ce que je peux dire (vu que l'on a pas le code ... et que d'un autre code.
    ==64910== Use of uninitialised value of size 4
    Cela peut etre a cause d'un code comme suit:]
    qui est a remplace par:
    ==64910== Invalid read of size 4
    Depassement memoire (vous allez en dehors de votre tableau, ou autre cas du genre ...

    ==64910== Address 0x3C15942C is 16 bytes inside a block of size 20 free'd
    Celle la, je ne conaissais pas, mais vous avez dit faire une tres mauvaise chose avec votre pointeur

    ==64910== Conditional jump or move depends on uninitialised value(s)
    Peut etre lie a la premiere.

    De plus, une compilation avec -g, je crois, donne les lignes des erreurs precisement (enfin, si je me rappelle bien)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    Ce serait bien que tu descendes de ton piédestal imaginaire Sve@r.
    Parce que figure toi que si c'est pour répondre "apprends à coder", autant ne pas répondre. Et aussi, pour ta gouverne, sache qu'un étudiant par définition n'est PAS très au point dans son domaine, sinon ce ne serait plus un étudiant mais un expert.

    De plus vous n'avez pas besoin de code pour répondre à ma question (sinon j'aurais bien pu vous saouler à poster du code bien obscure mais j'ai pensé que ça n'en valait pas la peine). Je sais à quoi est dû l'une des erreurs que je veux résoudre :
    J'ai donc regardé, et j'ai vu qu'une grosse part de mes problèmes semblaient resider dans ce genre de tests : if (elem).
    "elem" étant un élément d'un liste chainée.
    Sache aussi Sve@r, qu'une liste chainée qui n'est pas circulaire peut pointer sur rien. On appelle cela généralement la fin d'une liste. De plus, c'est une protection, pour éviter de seg_fault y paraît.

    Conclusion, si c'est pour être agressif et dire des choses inutiles, autant ne rien écrire merci.

    Sinon merci à toi LittleWhite pour ta réponse, même si tu as essayé de décortiquer mes erreurs et non répondre uniquement à ma question (j'ai tendance à traiter les erreurs par étapes ^^).

    J'ai quand même jeté un œil au lien de Sve@r, et j'ai vu que le tuto disait de faire pointer le dernier maillon sur NULL. Moi on m'a toujours appris à le faire pointer sur 0 et je ne connais pas entièrement la différence, c'est peut être la solution à mon problème.

    Et merci aussi pour le coup de la compilation en -g, je vais essayer sans.

  5. #5
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 579
    Points
    218 579
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par Nyromancer Voir le message
    J'ai quand même jeté un œil au lien de Sve@r, et j'ai vu que le tuto disait de faire pointer le dernier maillon sur NULL. Moi on m'a toujours appris à le faire pointer sur 0 et je ne connais pas entièrement la différence, c'est peut être la solution à mon problème.
    En regle generale, NULL est definit comme suit:
    Donc NULL et 0 c'est la meme chose. Juste que NULL, exprime bien que c'est un pointeur pointant sur rien.

    Citation Envoyé par Nyromancer Voir le message
    Et merci aussi pour le coup de la compilation en -g, je vais essayer sans.
    Euh, je parlais du '-g' pour le rajouter et non l'enlever. C'est pour que GCC laisse les informations de debugguage dans le programme se qui rendra le boulot de valgrind plus efficace.

    J'ai donc regardé, et j'ai vu qu'une grosse part de mes problêmes semblaient resider dans ce genre de tests : if (elem).
    "elem" étant un élément d'un liste chainée.
    Finalement, j'ai donne un descriptif des erreurs, car moi, je ne pense pas que cela vienne de la ...
    Mais apres, c'est vous qui avez le code sous les yeux
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  6. #6
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    Encore merci !

    Alors oui en effet je ne compilais pas avec -g (bien que connaissant) et je ne savais pas que cela aidait valgrind !

    J'ai réglé la plupart de mes erreurs en initialisant mes variables temporaires (pour faire plaisir à valgrind ^^) et je coince sur le free.

    Je post mon erreur :

    ==68508== Invalid read of size 4
    ==68508== at 0x80494AA: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==68508== by 0x8049518: destroy (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==68508== by 0x804A2EC: main (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==68508== Address 0x3C159A04 is 16 bytes inside a block of size 20 free'd
    ==68508== at 0x3C034687: free (in /usr/local/lib/valgrind/vgpreload_memcheck.so)
    ==68508== by 0x804B1F1: xfree (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==68508== by 0x8049ECF: del_elem (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    ==68508== by 0x804949F: destroy_list (in /home/nyromancer/prog_c/bonux/exec/aff_termcaps)
    et mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    t_lpath         *destroy_list(t_lpath *list)
    {
      if (list)
        {
          list = list->start;
          while (del_elem(list))
            list = list->next;
        }
      return (list);
    }
    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
    t_lpath         *del_elem(t_lpath *lpath)
    {
      t_lpath       *tmp;
     
      tmp = NULL;
      if (lpath)
        {
    /*si le précédent existe je change son pointeur next*/
          if (lpath->prev)
            {
              lpath->prev->next = lpath->next;
              tmp = lpath->prev;
            }
    /*si le suivant existe je change son pointeur prev*/
          if (lpath->next)
            {
              lpath->next->prev = lpath->prev;
              tmp = lpath->next;
            }
          xfree(lpath->path); /*path est une chaine de caractère*/
          xfree(lpath);
    /*je reconstruis les info après la suppr (qui? est maillon start actuel et je change les id, pas très utile dans notre cas mais dans d'autres oui)*/
          lpath = rebuild(tmp);
        }
      return (lpath);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void    *xfree(void *pt)
    {
    /*A l'époque je ne connaissais pas précisément la différence donc au cas ou je testais 0 et NULL*/
      if (pt && pt != NULL)
        free(pt);
      return (NULL);
    }

  7. #7
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Citation Envoyé par Nyromancer Voir le message
    J'ai réglé la plupart de mes erreurs en initialisant mes variables temporaires (pour faire plaisir à valgrind ^^) et je coince sur le free.
    Pas pour faire plaisir a Valgrind, mais pour rendre ton code correct.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    t_lpath         *destroy_list(t_lpath *list)
    {
      if (list)
        {
          list = list->start;
          while (del_elem(list))
            list = list->next;
        }
      return (list);
    }
    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
    t_lpath         *del_elem(t_lpath *lpath)
    {
      t_lpath       *tmp;
     
      tmp = NULL;
      if (lpath)
        {
    /*si le précédent existe je change son pointeur next*/
          if (lpath->prev)
            {
              lpath->prev->next = lpath->next;
              tmp = lpath->prev;
            }
    /*si le suivant existe je change son pointeur prev*/
          if (lpath->next)
            {
              lpath->next->prev = lpath->prev;
              tmp = lpath->next;
            }
          xfree(lpath->path); /*path est une chaine de caractère*/
          xfree(lpath);
    /*je reconstruis les info après la suppr (qui? est maillon start actuel et je change les id, pas très utile dans notre cas mais dans d'autres oui)*/
          lpath = rebuild(tmp);
        }
      return (lpath);
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void    *xfree(void *pt)
    {
    /*A l'époque je ne connaissais pas précisément la différence donc au cas ou je testais 0 et NULL*/
      if (pt && pt != NULL)
        free(pt);
      return (NULL);
    }
    A quoi ca te sert que xfree renvoit quelque chose, alors que tu retournes toujours NULL ?
    Pourquoi ne pas utiliser directement free, sachant que liberer un pointeur sur NULL n'est pas une erreur : http://man.developpez.com/man3/free.3.php
    Il est d'usage de passer une variable a NULL une fois qu'on l'a liberee : ca permet d'eviter des erreurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    /* du code ... */
    free (mon_petit_pointeur);
    mon_petit_pointeur = NULL;
    /* suite */
    Et enfin, sans savoir ce que fait rebuild, difficile de t'aider. Quoi que tu en dises, c'est plus simple de t'aider avec le code qu'avec juste les erreurs.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  8. #8
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    un truc qui m'embête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    while (del_elem(list))
            list = list->next;
    Si del_elem(list) efface l'élément courant sans changer de position dans la liste (next/prev/...).
    list = list->next est invalide car libéré.

    Si del_elem(list) efface , et déplace le pointeur sur next/prev/...
    list = list->next fait changer une seconde fois de position et donc on risque de manquer la libération d'un élément en passant a coté.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  9. #9
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    @gangsoleil
    Ben justement, xfree envoie 0 mais ne peut l'envoyer à un pointeur que sous la forme d'un pointeur valant 0. Vu que c'est fait à chaque fois ça économise des lignes répétitives et ça éclairci le code. Et essaye de free un pointeur NULL, moi ça me met des erreurs pas jolies sans valgrind, alors avec t'imagines pas. ^^

    Pour le "pour faire plaisir à valgrind", tu as raison vaut mieux être sûr à 100% et régler les erreurs valgrind.

    Et pour rebuild j'ai mis en commentaire
    /*je reconstruis les info après la suppr (qui? est maillon start actuel et je change les id, pas très utile dans notre cas mais dans d'autres oui)*/
    Et voici le code :
    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
    t_lpath         *rebuild(t_lpath *elem)
    {
      t_lpath       *start;
      t_lpath       *tmp;
     
      start = NULL;
      tmp = NULL;
      if (elem)
        {
          tmp = elem;
          start = elem->start;
          if (!(elem->prev))
            {
              start = elem;
              elem->id = 0;
            }
          elem->start = start;
          while (elem && elem->next)
            {
              elem->next->start = start;
              elem->next->id = elem->id + 1;
              elem = elem->next;
            }
          elem = tmp;
        }
      return (elem);
    }
    @jabbounet
    Hum tu mets le doigt sur un truc je vais me pencher dessus plus profondément, merci.

  10. #10
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    @jabbounet
    Merci oeil de lynx, c'était ça le problème en fait. Avant en fait je faisais de manière simple ma destruction de liste par un :

    while (elem)
    {
    tmp = elem->next;
    free(elem);
    elem = tmp;
    }

    ou un truc du genre. Et j'ai implémenté del_elem pour pouvoir supprimer n'importe où dans la chaine et j'ai bâclé le travail d'adaptation du code.

    Encore merci.

  11. #11
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 579
    Points
    218 579
    Billets dans le blog
    120
    Par défaut
    Je ne comprends pas le pourquoi les xfree(). Utilisez vous xmalloc() ? ou la Xlib? ()

    Et essaye de free un pointeur NULL
    Faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    free(NULL);
     
    // ou encore
    int* pI = NULL;
    free(NULL);
    Est legal et ne produit aucune erreur.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  12. #12
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    Au temps pour moi pour le xfree. Je ne savais pas et avait eu de mauvaises expériences de messages mettant "chunk is already free", j'avais mis ça sur le dos de la valeur passé à free qui, je le pensais, ne voulait pas free un pointeur NULL.
    Je m'excuse encore et vous remercie (encore). ^^

    Le seul avantage de xfree c'est de pouvoir faire "pt = xfree(pt);" du coup, ca clarifie un peu le code en mettant systématiquement le pointeur à 0.

  13. #13
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par Nyromancer Voir le message
    Le seul avantage de xfree c'est de pouvoir faire "pt = xfree(pt);" du coup, ca clarifie un peu le code en mettant systématiquement le pointeur à 0.
    L'inconvénient est quand tu fait une faute d'orthographe, suite a un mauvais copier/coller .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    truc   *pt1 = malloc(...);
    bidule *pt2 = malloc(...);
     
    /* plein de code */
    ...
     
    pt1= xfree(pt1);
    pt2= xfree(pt1);
    tu peux tout aussi bien le remplacer par une macro par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define xfree(data)    \
        free( (data) );       \
        data = NULL;
    Et si tu fait pareil pour les alloc et que tu ajoute un petit compteur ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #define xmalloc(size)    \
        malloc( (size) );       \
        nbAlloc++;
     
    #define xfree(data)                         \
        if ( (data) != NULL) { nbFree++; }  \
        free( (data) );                            \
        data = NULL;
    A la fin de de l'exécution de ton programme si NbAlloc > nbFree tu as une fuite mémoire.
    Ce n'est pas parfait (très rudimentaire même), pas aussi précis que valgrind, mais cela te permet de faire un check rapide.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  14. #14
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    Sympa l'idée du define pour le free (celle aussi pour le compteur mais c'est vraiment pour debug pas plus ^^). Le truc c'est que les fonctions xMaChIn viennent de mes débuts où j'les avais mise dans une lib perso que je link à la compilation, si je réutilise ce système que je trouve moyen, c'est par manque de temps. Mais merci quand même pour l'idée j'la garde dans un coin de cerveau.

  15. #15
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nyromancer Voir le message
    Ce serait bien que tu descendes de ton piédestal imaginaire Sve@r.
    Parce que figure toi que si c'est pour répondre "apprends à coder", autant ne pas répondre. Et aussi, pour ta gouverne, sache qu'un étudiant par définition n'est PAS très au point dans son domaine, sinon ce ne serait plus un étudiant mais un expert.
    Ouh mais il est vexé ??? C'est quand-même pas moi qui suis arrivé en disant "j'ai un problème mais je vous dit pas comment ni où car je suis un étudiant newbee et aussi un petit peu boulet sur les bords !!!"

    Citation Envoyé par Nyromancer Voir le message
    De plus vous n'avez pas besoin de code pour répondre à ma question
    Ouais. Si tu le dis...

    Citation Envoyé par Nyromancer Voir le message
    (sinon j'aurais bien pu vous saouler à poster du code bien obscure
    Parce qu'en plus tu ne mets pas de commentaire dans ton code bien obscur (sans "e") ?
    C'est vrai que les commentaires c'est un truc d'expert et pas un truc d'étudiant...

    Citation Envoyé par Nyromancer Voir le message
    Sache aussi Sve@r, qu'une liste chainée qui n'est pas circulaire peut pointer sur rien.
    Vas-y, sors moi ta science toute nouvelle du haut de tes 7 posts. Surtout que ça ne change rien à ce que j'ai dit. Un maillon de liste ne peut pas être égal à 0 de par son existence même. Si le maillon existe c'est qu'il est à une adresse réelle donc pas 0. C'est le pointeur next d'un maillon existant qui peut avoir la valeur nulle. Je te pensais au-moins capable de faire la différence entre "être égal à 0" et "avoir (dans un de ses éléments) une valeur à 0". Probablement encore un truc d'expert...

    Le plus amusant c'est que j'y ai pensé figure-toi, qu'il se pouvait que tu aies atteint la fin de ta liste dans une boucle où tu récupérais elem->next dans elem. Mais je me suis dit "non c'est pas possible, il n'est pas idiot à ce point, il a au-moins pris la peine de vérifier que elem->next n'est pas nul pour éviter une affectation inutile". Hé ben non, je t'avais surestimé...

    Citation Envoyé par Nyromancer Voir le message
    On appelle cela généralement la fin d'une liste. De plus, c'est une protection, pour éviter de seg_fault y paraît.
    Pfff. En plus t'as même pas réfléchi à ce que tu lisais !
    On ne met pas NULL (ou 0 ce qui est la même chose) pour éviter un seg_fault !!! On positionne le pointeur next du dernier élément à NULL SIMPLEMENT pour montrer que le dernier élément EST le dernier. Parce que si on ne le faisait pas alors le pointeur next du dernier élément contiendrait n'importe quoi et on ne pourrait pas faire la différence entre un elem->next qui contient une adresse valide et un elem->next qui contient n'importe quoi et donc on ne saurait pas qu'on se trouve sur le dernier et donc, en allant taper dans le next, on taperait alors n'importe où dans la mémoire ce qui provoquerait PROBABLEMENT un "seg_fault" (car ce n'est même pas garanti).
    On appelle ce NULL une "valeur sentinelle". Tu pourras ressortir le terme lors d'un de tes prochains cours pour briller un minimum en faisant croire que tu sais lire un tuto...

    Citation Envoyé par Nyromancer Voir le message
    J'ai quand même jeté un œil au lien de Sve@r, et j'ai vu que le tuto disait de faire pointer le dernier maillon sur NULL. Moi on m'a toujours appris à le faire pointer sur 0 et je ne connais pas entièrement la différence, c'est peut être la solution à mon problème.
    Ce sont deux valeurs identiques mais l'une est conventionnellement employée pour les pointeurs et l'autre pour les variables de type entier. Il y a autant de différence entre NULL et 0 qu'entre '0' et 48.

    Citation Envoyé par Nyromancer Voir le message
    Conclusion, si c'est pour être agressif et dire des choses inutiles, autant ne rien écrire merci.
    Conclusion, la prochaine fois poste ton code comme le font 99,9% de ceux qui viennent ici avec un problème, au-lieu de nous faire jouer les devins merci.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #16
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 8
    Points : 0
    Points
    0
    Par défaut
    Franchement, au risque de me répéter, si c'est pour parler inutilement ne parle pas (bon sauf pour le KiKoO nombre de posts).

    On évite un seg_fault (qui ne devrait normalement pas avoir lieu, mais je préfère coder de la manière la plus sûre possible et on ne contrôle pas toujours toutes les données) en testant le maillon pour éviter d'essayer de travailler sur rien.
    exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    list = NULL;
    list = list->next;
    Ne commente pas cela, je sais que tu sais et ne pense pas te l'apprendre (ni dans mes posts d'avant. Je te montre juste que tu as bien lu ce qu'il t'amusait de lire (c'est mon sentiment en te lisant en tout cas, j'ai eu l'impression que tu t'es dis "Encore un naze qui sait pas coder et qui vu qu'on lui fasse tout", ou un truc du genre).

    Fais quand même un effort pour ne pas tout prendre de haut tu veux ? Et si tu regardes bien, tous les autres posts on presque dit la même chose que ce que tu aurais dit mais m'ont aidés eux.

    Tu peux bien sûr me répondre mais je ne lirai pas, j'ai autre à faire que de m'attarder sur si peu.
    Je n'espère pas trop que tu changes mais bon j'reste un peu naïf.
    Ah et puis aussi, reprendre quelqu'un sur les fautes c'est...une preuve de manque de répartie.

    P.S.:J't'ai un peu relu et, tu lis vraiment c'que tu veux lire non ? C'est assez marrant comme tu prendre pour argent content et comme opinion finale une simple lecture rapide. Pourquoi arrêter ton jugement ? T'es psychorigide ?

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

Discussions similaires

  1. Réponses: 11
    Dernier message: 13/05/2013, 16h59
  2. [AC-2003] besoin d'aide liste deroulante
    Par revemane dans le forum IHM
    Réponses: 4
    Dernier message: 09/04/2011, 19h31
  3. Besoin d'aide pour mon script sur les listes chainées
    Par narama87 dans le forum Débuter
    Réponses: 1
    Dernier message: 13/01/2011, 12h29
  4. Debutant besoin Aide liste chainé
    Par flingue dans le forum Débuter
    Réponses: 7
    Dernier message: 29/12/2008, 17h00
  5. [PHP-JS] Liste déroulante + Javascript + Php et Mysql : Besoin d'aide
    Par vampyrx dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/03/2006, 01h40

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