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 :

Erreur étonnante à propos des pointeurs!


Sujet :

C++

  1. #1
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut Erreur étonnante à propos des pointeurs!
    Salut à tous!
    En fait c'est une erreur dont je cherches la solution il y a environ une semaine.
    En fait je crée un pointeur vers une instance de la classe "Chemin".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        Chemin * travail = depart;
    depart est un attribut de la classe itineraire et qui est pointeur vers une instance de la classe "Chemin".
    voici l'implémentation de la fameuse classe "Chemin":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        #include "Case.h"
        class Case;
        class Chemin
        {
        friend class Itineraire;
        private:
        Chemin(int ligne, int colonne):m_case(ligne,colonne){}
              Chemin(Case const & c):m_case(c){}
        Chemin(Chemin const &);
        Chemin(void):m_case(0,0){}
        Case m_case;
                Chemin* m_next;
        };
    et dès que j'appelle la case "m_case" toutes les valeurs de l'instance sur laquelle on pointe changent!!
    donc après cette ligne de code:

    tout change!
    enfin voici l'implémentation de la classe case :

    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
        class Case
        {
           friend class Itineraire;
        private:
     
           int ligne;
           int colonne;
     
        public:
     
     
           int get_Ligne() const;
           int get_Col()const ;
           void set_Ligne(const int);
           void set_Colonne(const int);
           Case(void):ligne(0),colonne(0){};
           Case(int,int);
           ~Case(void);
        };
    Veuillez me donnez quelques explications ...

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Si tu veux qu'on résolve rapidement le problème, il faudrait un bout de code *minimale* et *compilable* qui reproduit le problème, avec quelques printf avant/après des attributs en question, parce que pour le moment c'est assez difficile de se faire une idée de ce que tu veux dire par "un appel à la case m_case" qui ferait "changer les valeurs de l'instance sur laquelle on pointe".
    Merci.

  3. #3
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    Voici la méthode qui accède à "m_case"
    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
    void Itineraire::afficher() const
    {
     
     
        Chemin * travail = depart;
     
       while(travail) 
       {
     
     
     
    	  cout<< "("<<travail->m_case.get_Col() ;
    	   cout	   <<","<<travail->m_case.get_Ligne();
              cout<<")"<<std::endl;
     
    		  travail=travail->m_next;
     
     
       }
    }
    et- "Itineraire.h" sera
    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
    #include "Grille.h"
    #include "Case.h"
    #include "Chemin.h"
    #include <iostream>
    using namespace std;
    class Case;
    class Itineraire
    {
     
    private:
     
    	Chemin *depart;
    	Chemin *arrivee;
     
     
     
     
     
    public:
    	Itineraire(void);
    	Itineraire(Chemin* depart);
    	~Itineraire(void);
    	void add(Case const&);
    	void afficher() const;
    };

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Ton erreur me fait penser à un problème de pointeur. As-tu vérifier que la création de ta liste se passe bien ? Comment est initialisé m_next ?

  5. #5
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    En fait lorsque j'initialise m_next à NULL il m'affiche une erreur"identificateur non déclaré"(mais parfois il exécute sans rien afficher et dès qu'on fait une autre erreur il revient à cette erreur d'"identificateur non déclaré")

  6. #6
    Membre actif
    Inscrit en
    Août 2008
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Août 2008
    Messages : 47
    Par défaut
    Je suis le seul à penser que c'est anormal de donner le nom case à une classe puisque c'est un mot réservé?.

  7. #7
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Oui, car le mot clef réservé est case et non Case... (la casse compte, y'a que le parser du forum qui a pas l'air d'en tenir compte).
    Même si je te l'accorde ça peut prêter à confusion..

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    une structure qui change toute seule comme cela, a ma connaissance cela ne peut être qu'une erreur mémoire et justement, comme tu ne donne pas de valeur par défaut à m_next de ta classe Chemin, ce pointeur peut valoir n'importe quoi .
    Et quand tu fait ta boucle sur les chemins, tu tombe sur cette valeur non initialisé de pointeur et lors de tes appels, tu produits une erreur mémoire et rend l'état de ton programme indéterminé.

    Pour ton problème de compilation sur la mise à 0 de m_next, il faudrait voir ton code, pour te dire ce qui ne va pas.

  9. #9
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    Citation Envoyé par yan Voir le message
    une structure qui change toute seule comme cela, a ma connaissance cela ne peut être qu'une erreur mémoire et justement, comme tu ne donne pas de valeur par défaut à m_next de ta classe Chemin, ce pointeur peut valoir n'importe quoi .
    Et quand tu fait ta boucle sur les chemins, tu tombe sur cette valeur non initialisé de pointeur et lors de tes appels, tu produits une erreur mémoire et rend l'état de ton programme indéterminé.

    Pour ton problème de compilation sur la mise à 0 de m_next, il faudrait voir ton code, pour te dire ce qui ne va pas.
    En fait comme je l'ai dit le compilateur ne m'a pas laissé l'occasion d'initialiser m_next à NULL et en faite dès que j'entre dans la boucle "while(travail){...}"
    et après la ligne ci-dessous tout change (donc on n'a pas encore accédé à m_next!)
    cout<< "("<<travail->m_case.get_Col() ;
    et à propos du code je pense que j'en ai donné suffisamment ,presque toutes les classes qui ont un lien avec l'erreur produite sont en dessus.

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Bonjour,
    Citation Envoyé par dingua Voir le message
    et à propos du code je pense que j'en ai donné suffisamment ,presque toutes les classes qui ont un lien avec l'erreur produite sont en dessus.
    Non, il manque toute la construction et l'initialisation de ta liste. Comme dit dans mon premier message et comme dit par Yan, je penche pour un problème de pointeur mal initialisé.

  11. #11
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par dingua Voir le message
    le compilateur ne m'a pas laissé l'occasion d'initialiser m_next à NULL
    Pour être puriste c'est 0 et non NULL en c++
    Sinon, ce n'est pas normale , l'initialisation d'un pointeur à 0 (ou NULL) ne doit pas poser de problème.
    Il faudrait que tu montre un peu plus de code. Dans ce que tu as montré, à par la non initialisation de m_next, il ne semble pas qu'il y est d'autre problème.

    Si tu peut utiliser boost, Qt ou autre (y as surement des lib moins lourde, peut être loki), ces lib fournissent des pointeurs intelligent bien plus agréable et moins case gueule à utiliser :
    http://loic-joly.developpez.com/tuto...mart-pointers/
    http://matthieu-brucher.developpez.c...ost/smartptrs/

  12. #12
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    J'ai utilisé 0 à la place de "NULL" ;alors le compilateur l'a accepté mais on se trouve dans le même cas; je peux vous donnez un autre point qui peut aider,c'est que dès que je construis une Case dans la méthdoe Itineraire::afficher() toutes les valeurs des instances pointés par "départ"change.
    Tout ça se déroule sans que l'adresse du pointeur change!

  13. #13
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Surement que soit depart soit le pointeur sur Itineraire (si tu utilise un pointeur) pointe sur n'importe quoi .

  14. #14
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    Citation Envoyé par yan Voir le message
    Surement que soit depart soit le pointeur sur Itineraire (si tu utilise un pointeur) pointe sur n'importe quoi .
    je ne suis pas du tout convaincu par ce que tu dis yan,car en "déboguant" je découvre qu'avant l'appel de "m_case" tout va bien mais juste après toutes les valeurs changent sans que les adresses des pointeurs le font!

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Citation Envoyé par dingua Voir le message
    je ne suis pas du tout convaincu par ce que tu dis yan,car en "déboguant" je découvre qu'avant l'appel de "m_case" tout va bien mais juste après toutes les valeurs changent sans que les adresses des pointeurs le font!
    Ce genre de bug j'en ai fait et j'en ai corrigé pas mal
    Mais rien ne t'empêche de vérifier la valeur de "depart" et, si tu utilise un pointeur, celui de l'instance Itineraire.

    Peut tu montrer comment tu initialise tes pointeurs?

  16. #16
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    voici le constructeur de l'instance Itineraire que j'utilise:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Itineraire::Itineraire(Chemin * d):depart(d),arrivee(NULL)
    {
     
    }
    et la déclaration du pointeur vers l'instance itineraire est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Itineraire* itineraire=new Itineraire( &Chemin(a));

  17. #17
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Itineraire( &Chemin(a));
    en voila un jolie bug. Tu passe en paramètre un pointeur sur une variable temporaire. Une fois qu'elle est détruite ton pointeur est invalide

  18. #18
    Membre averti
    Inscrit en
    Mai 2009
    Messages
    56
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 56
    Par défaut
    Merci, c'était vraiment ça!

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 25/06/2011, 22h14
  2. Réponses: 6
    Dernier message: 05/05/2010, 15h21
  3. A propos des pointeurs
    Par emprex dans le forum Débuter
    Réponses: 3
    Dernier message: 26/03/2010, 15h29
  4. Erreurs de compilation des pointeurs
    Par hanry dans le forum Débuter
    Réponses: 7
    Dernier message: 18/03/2008, 14h34
  5. à propos des pointeurs
    Par salseropom dans le forum C++
    Réponses: 20
    Dernier message: 24/03/2005, 09h37

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