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 :

Problème avec les listes chainées


Sujet :

C++

  1. #1
    Membre habitué Avatar de reeda
    Formateur en informatique
    Inscrit en
    Août 2006
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 367
    Points : 150
    Points
    150
    Par défaut Problème avec les listes chainées
    Salut tout le monde,

    SVP, j'ai écrit un petit code qui me permet d'ajouter un nouvel élément dans une liste chainée,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void RA_Blocks::ajouter (RA_Page rap)
    {
    	liste *nouv;
    	nouv=new liste;
    	nouv->rapage=rap;
    	nouv->suiv=Les_RA_Pages;
    	Les_RA_Pages=nouv;
    	nb_ra_pages++;
    }
    la définition de la classe est la suivante :
    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
    #if !defined(AFX_RA_BLOCKS_H__AF8B6C62_E94D_4F27_97BF_961318027A4F__INCLUDED_)
    #define AFX_RA_BLOCKS_H__AF8B6C62_E94D_4F27_97BF_961318027A4F__INCLUDED_
     
    #if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
     
    #include "RA_Page.h"
     
    struct liste{
    	RA_Page rapage;
    	liste *suiv;
    };
     
    class RA_Blocks 
    {
     
      public:
    	RA_Blocks();
    	RA_Blocks(int n, liste *list);
    	RA_Blocks(const RA_Blocks &right);
    	~RA_Blocks();
    	RA_Blocks & operator=(const RA_Blocks &right);
    	int operator==(const RA_Blocks &right) const;
    	int operator!=(const RA_Blocks &right) const;
    	void ajouter (RA_Page rap);
    	void afficher ();
    	int nb_RA_Page ();
     
      private: 
          liste *Les_RA_Pages;
    	  int nb_ra_pages;
     
    };
     
    #endif
    Quand je compile, 0 Errors et 0 Warnings
    Mais quand j'exécute, ca se bloque, ca passe pas

    je ne sais vraiment pas d'où ca vient.

    merci d'avance
    Bien cordialement

  2. #2
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Salut,

    Ne crée pas ta propre structure, utilise l'officielle et correcte std::list (edit: surtout que là tu n'as même pas la notion de conteneur, tu as juste déclaré la composition d'un maillon de la liste )

  3. #3
    Membre habitué Avatar de reeda
    Formateur en informatique
    Inscrit en
    Août 2006
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 367
    Points : 150
    Points
    150
    Par défaut
    Citation Envoyé par IrmatDen Voir le message
    Salut,

    Ne crée pas ta propre structure, utilise l'officielle et correcte std::list (edit: surtout que là tu n'as même pas la notion de conteneur, tu as juste déclaré la composition d'un maillon de la liste )
    salut,

    je crois que je n'ai pas compri ta réponse,
    un petit boue de code qui explique ca, m'aiderai à mieux comprendre votre réponse.

    merci d'avance
    Bien cordialement

  4. #4
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Salut,

    je crois que le meilleur moyen de trouver ce qui cloche dans un code est de le débugger. Peux-tu fournir un code assez complet pour être compilable?

    La classe template std::list permet de créer des listes chainées d'éléments du même type, quelqu'il soit. Il suffit d'inclure <list>

  5. #5
    Membre éclairé Avatar de HanLee
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2004
    Messages : 738
    Points : 871
    Points
    871
    Par défaut
    Petit tutorial : http://cpp.developpez.com/cours/stl/#LIII-A

    Citation Envoyé par IrmatDen Voir le message
    Salut,

    Ne crée pas ta propre structure, utilise l'officielle et correcte std::list (edit: surtout que là tu n'as même pas la notion de conteneur, tu as juste déclaré la composition d'un maillon de la liste )
    La notion de conteneur est une notion qui "vient du C++", son "maillon" correspond très bien à la définition récursive d'une liste par contre.

    Mais ne crois pas que je ne l'encourage pas à utiliser std::list hein.

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Salut,

    Je crains que le problème soit principalement algorithmique...

    Déjà, il me semblerait utile de donner des noms plus explicite à tes types et à tes membres, et, sans doute, de rajouter un pointeur sur le dernier élément de la liste .

    Ainsi, ta classe liste représente, en réalité, un maillon, et je te proposerais donc de la renommer en "Maillon", pour lui donner une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    struct Maillon
    {
        RA_page page;
        Maillon * suivant;
        /* je rajoute un constructeur dont je m'assure qu'il ne servira pas
         * d'opérateur de conversion implicite
         */
        explicit Maillon(const RA_page& page, Maillon * suivant=NULL):page(page),
        suivant(suivant)
        {
        }
    };
    Par contre, la classe RA_Blocks est... la liste en elle-même, et je t'encouragerais donc à renommer en... Liste, en lui donnant la forme de
    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
    class Liste
    {
        public:
            Liste();
    	Liste(int n, Maillon*list);/* j'ai laissé n, mais il n'est pas forcément nécessaire ;) */
    	Liste(const Liste &right);
    	~Liste();
    	Liste & operator=(const RA_Blocks &right);
    	int operator==(const Liste &right) const;
    	int operator!=(const Liste &right) const;
    	void ajouter (RA_Page rap);
    	void afficher ();
            /*Autant rester "const correct" ;) */
    	size_ nb_RA_Page () const; /* voir plus bas pour "size_t" */
       private:
            /* en ayant le premier et le dernier élément de la liste, tu te
             * donne l'occasion de rajouter un élément en fin de liste en 
             * temps constant
             * en plus, cela te facilitera le travail si tu décide un jour de 
             * permettre l'insertion en début de liste ;)
             */
            Maillon * premier; /* le premier élément de la liste */
            Maillon * derenier;/* le dernier élément de la liste */
            /* comme il n'y aura jamais... -1 éléments, autant utiliser une valeur
             * non signée, dont on est sur qu'elle permettra de représenter
             * l'ensemble des valeurs "potentielles" ;)
             */
            size_t nb_maillon; /* le nombre d'éléments dans la liste */
    };
    L'implémentation des méthodes prendrait la forme de
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    /*création d'une liste vide */
    Liste::Liste():premier(NULL),dernier(NULL),nb_maillon(0)
    {
    }
    /* n ne sera pas utilisé ;) */
    Liste::Liste(int n, Maillon *list):premier(NULL),dernier(NULL)
    {
        /* nous allons créer une boucle qui va copier chacun des maillons 
         * reçu par le constructeur
         */
        while(liste!=NULL)
        {
            /* on copie le maillon */
            Maillon * temp=new Maillon(list->page);
            /* C'est peut être le premier maillon */
            if(!premier)
            {
                /* dans ce cas, temp est tout à la fois premier et dernier maillon */
                premier=temp;
             }
             else
             {
                 /* sinon, on lie le dernier maillon à temp */
                 dernier->suivant=temp;
                 /* et temp devient le dernier maillon */
             }
             /* et, bien sur, on incrémente le nombre de maillon */
             dernier=temp;
             ++nb_maillon;
        }
    }
    /* Le constructeur par copie travaille exactement de la meme manière:
     * En effet, on  ne peut pas se permettre de faire partager les maillons par
     * plusieurs listes
     */
    Liste::Liste(const Liste &right):premier(NULL),dernier(NULL),nb_maillon(0)
    {
        /* nous allons créer une boucle qui va copier chacun des maillons 
         * reçu par le constructeur
         */
        Maillon list=right->premier;
        while(list!=NULL)
        {
            /* on copie le maillon */
            Maillon * temp=new Maillon(list->page);
            /* C'est peut être le premier maillon */
            if(!premier)
            {
                /* dans ce cas, temp est tout à la fois premier et dernier maillon */
                premier=temp;
             }
             else
             {
                 /* sinon, on lie le dernier maillon à temp */
                 dernier->suivant=temp;
             }
             /* et temp devient le dernier maillon */
             dernier=temp;
             /* et, bien sur, on incrémente le nombre de maillon */
             ++nb_maillon;
        }
    }
    /* le destructeur s'occupe de détruire tous les maillons */
    Liste::~Liste()
    {
     
        while(premier!=NULL)
        {
            /* on garde une trace de l'élément qui suit le premier maillon */
            Maillon * temp=premier->suivant;
            /* on libère la mémoire du premier maillon */
            delete premier;
            /* l'élément qui suivait le premier maillon devient premier maillon */
            premier = temp;
        }
    }
    /* Je te laisse du travail pour les opérateurs d'affectation et 
     * de comparaison, ainsi que les accesseurs simples ;)
     */
    void Liste::ajouter(RA_Page rap)
    {
        /* je considère que, ici, on ajoute d'office en fin de liste ;) 
         * L'idéal serait toute fois d'avoir
         *    -AjouterDebut
         *    -AjouterFin
         *    -AjouterApres(element, a_ajouter)
         *    -éventuellement, pouvoir passer des Maillons directement comme
         *     surcharge de ces trois méthodes ;)
         */
        /* on crée le nouveau maillon */
        Maillon * temp=new Maillon(rap);
        /*c'est peut etre le premier maillon de la liste */
        if(!premier)
        {
            premier = temp;
        }   
        else
        {
            dernier->suivant=temp;
        }
        dernier=temp;
        ++nb_maillon;
    }
    Maintenant, il faut savoir que le C++ fournit une classe qui permet de travailler de manière bien plus simple, même si, pour l'instant, il ne s'agit que d'une liste "doublement chainée" (la prochaine norme devrait fournir une classe de liste "simplement chainée): la classe list, disponible dans l'espace de noms std en incluant le fichier d'en-tête <list>

  7. #7
    Membre expert

    Avatar de IrmatDen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 727
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 727
    Points : 3 266
    Points
    3 266
    Par défaut
    Citation Envoyé par HanLee Voir le message
    La notion de conteneur est une notion qui "vient du C++", son "maillon" correspond très bien à la définition récursive d'une liste par contre.

    Mais ne crois pas que je ne l'encourage pas à utiliser std::list hein.
    Non non Merci de la précision au contraire.

  8. #8
    Membre habitué Avatar de reeda
    Formateur en informatique
    Inscrit en
    Août 2006
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 367
    Points : 150
    Points
    150
    Par défaut
    salut les amis,

    je vous remerci beaucoup pour toutes vos réponses, elles sont toutes trés interessantes.

    Mais je crois que le problème que j'ai viens du fait que mon projet est un peu lourd car j'implémente une structure de données un peu complexe, il y a en tout 7 classes, chacune contient des pointeurs, des objets d'autres classes, ...

    Quand j'ai voulu faire un grand exemple même d'autres fonctions que j'utilisais sans problème sur des exemples plus petits ne marchent plus maintenant.

    Ca donne le truc de :


    Donc je ne pense pas que c'est un problème qui vient du code mais plutot de la mémoire, et la liste chainnée que je veux créer se bloque parce que celle ci contient des objets d'un type qui rassemble toutes les classes créés dans mon projet.

    Et j'ai remarqué aussi que ce problème survient quand je crée un pointeur sur un objet des classes de mon projet.

    Et maintenant, je ne sais plus quoi faire.

    P.S. : j'utilise VC++ 6.0 comme EDI

    Merci beaucoup
    Bien cordialement

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 382
    Points : 41 589
    Points
    41 589
    Par défaut
    Compile le projet en mode Debug, lance-le dans le debugger de Visual, et lors du plantage, regarde où ça plante...
    La fenêtre "call stack" peut t'être utile...

  10. #10
    Membre habitué Avatar de reeda
    Formateur en informatique
    Inscrit en
    Août 2006
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 367
    Points : 150
    Points
    150
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Compile le projet en mode Debug, lance-le dans le debugger de Visual, et lors du plantage, regarde où ça plante...
    La fenêtre "call stack" peut t'être utile...
    oké merci, je vais essayer votre proposition.
    J'ai remarqué aussi que ce problème se manifest quand j'oubli d'initialiser un pointeur.

    Bien cordialement

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 631
    Points : 30 707
    Points
    30 707
    Par défaut
    Citation Envoyé par reeda Voir le message
    oké merci, je vais essayer votre proposition.
    J'ai remarqué aussi que ce problème se manifest quand j'oubli d'initialiser un pointeur.

    Bien cordialement
    C'est peut etre tout simplement là, le problème

    En mode "debug", tu peux, parfois, trouver des pointeur initialisés d'office à NULL (ou à 0), mais, en mode release, si tu n'initialise pas un pointeur, sa valeur d'origine est... tout et n'importe quoi (la valeur qui se trouve en mémoire de la dernière fois qu'elle a été utilisée... y compris par d'autres applications... autrement dit: des crasses )

    C'est l'une raisons principales pour lesquelles on déconseille toujours très fortement l'utilisation des pointeurs, à moins qu'il n'y ai pas moyen de faire autrement, et que l'on conseille toujours d'utiliser des classes dont on soit sur qu'elles ont été triturées et testées dans tous les sens...

    La bibliothèque standard est l'une des bibliothèques fournissant des classes entrant dans cette catégorie

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

Discussions similaires

  1. Problème avec les listes chainées
    Par Naswd_94 dans le forum Débuter
    Réponses: 8
    Dernier message: 09/03/2015, 11h40
  2. un problème avec les listes chainées
    Par chmek firas dans le forum Débuter
    Réponses: 4
    Dernier message: 05/05/2012, 07h55
  3. Problème avec les listes chainées
    Par t-mac06 dans le forum Débuter
    Réponses: 12
    Dernier message: 26/01/2012, 21h57
  4. petit problème avec les listes chainées
    Par djinpark1 dans le forum Débuter
    Réponses: 4
    Dernier message: 30/06/2009, 18h11

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