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 :

altération d'information d'un vector


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 13
    Par défaut altération d'information d'un vector
    Bonjour, je suis en cours de création d'un jeu vidéo en C++ avec DirectX dans le cadre de mes études, et je me heurte à un problème peu commun. J'ai un vector déclaré dans une de mes classes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vector<Objet_Mobile> objet;
    Ce vector est soumis à plusieurs ajout d'Objet_Mobile au cours du programme, mais, soudain, les informations qu'il contient se retrouvent altérée. Pour être un peu plus clair, voici quelques variables de la classes objet_mobile :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	int point_de_vie;
            D3DXVECTOR3* position;
            D3DXVECTOR3* rotation;
            D3DXVECTOR3* taille;
    	int index,state,poids;
    Les informations position et rotation ne sont en rien modifié, mais, environ au 30e élément, son membre taille se modifie à chaque listage du vecteur.

    Le membre taille n'est pourtant jamais accédé dans le programme.

    J'espère que je suis assez clair, mais, ce problème est très obscure pour moi.

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ça ressemble à un problème de dépassement de buffer, ou de pointeur fou...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 13
    Par défaut
    ben, j'ai regarder la capacité du vector, mais, le premier bug ne survient pas lors de la réalocation du vector.
    Et, sinon, tu connait un bon asile pour pointeur ??

    anytihing else? =)

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 13
    Par défaut
    Bon j'ai essayer avec une List au lieu d'un vector, et ça fonctionne ;]

    Tant mieux mais bon si quelqu'un à une idée avec le vector, je suis toujours preneur =)
    Woot woot =)

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    C'est sans doute une question idiote, mais, pourquoi gères-tu les membres position, taille et rotation sous la forme de pointeurs

    Sinon, J'irais sans doute voir s'il n'y a pas un problème du côté de ces membres, à l'occasion d'une copie d'éléments: étant donné que tu travailles sur des pointeurs, un new oublié pourrait très bien occasionner ce genre de problème
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 13
    Par défaut
    Bon j'ai essayer avec une List au lieu d'un vector, et ça fonctionne ;]

    Tant mieux mais bon si quelqu'un à une idée avec le vector, je suis toujours preneur =)
    Woot woot =)

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 13
    Par défaut
    Pour répondre à la question, je gère des pointeurs pour plus de facilité et de lisibilité du reste du code. Ensuite, le seul new qui apparait est fixé, et est lors de l'appel au constructeur, ainsi, il ne devrait pas y avoir de bug sur 1 objet précis mais sur tous (ils ont tous le même appel). Voila, merci pour vos réponse.

  8. #8
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Tu as seulement dû déplacer le problème et non l'éliminer.
    Tôt ou tard il te retombera dessus sois en sûr

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Pour te donner un exemple de ce que j'essaye de t'expliquer, je me suis amusé à écrire le petit code suivant
    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
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    #include <iostream>
    using namespace std;
     
    class Member
    {
        public:
            Member(){}
            Member(const Member&){}
            ~Member(){}
        protected:
     
        private:
    };
     
    class BadCopyable
    {
        public:
            BadCopyable()
            {
                m1=new Member();
                m2=new Member;
            }
            ~BadCopyable()
            {
                delete m1;
                delete m2;
            }
            void print()
            {
                cout<<"\tadresse de m1 "<<m1<<endl
                    <<"\tadresse de m2 "<<m2<<endl;
            }
            Member* m1;
            Member* m2;
     
    	protected:
     
    	private:
    };
    class WellCopyable
    {
        public:
            WellCopyable()
            {
                m1=new Member();
                m2=new Member;
            }
            WellCopyable(const WellCopyable& rhs)
            {
                m1=new Member(*rhs.m1);
                m2=new Member(*rhs.m2);
            }
            WellCopyable& operator=(const WellCopyable& rhs)
            {
                m1=new Member(*rhs.m1);
                m2=new Member(*rhs.m2);
            }
            ~WellCopyable()
            {
                delete m1;
                delete m2;
            }
            void print()
            {
                cout<<"\tadresse de m1 "<<m1<<endl
                    <<"\tadresse de m2 "<<m2<<endl;
            }
            Member* m1;
            Member*m2;
        protected:
        private:
    };
    class NonCopyable
    {
        public:
            NonCopyable()
            {
                m1=new Member();
                m2=new Member;
            }
            ~NonCopyable()
            {
                delete m1;
                delete m2;
            }
            void print()
            {
                cout<<"\tadresse de m1 "<<m1<<endl
                    <<"\tadresse de m2 "<<m2<<endl;
            }
            Member* m1;
            Member*m2;
        protected:
        private:
            NonCopyable(const NonCopyable&);
            void operator=(const NonCopyable&);
    };
     
    int main()
    {
        cout<<"avec la classe BadCopyable"<<endl;
        BadCopyable bc1;
        BadCopyable bc2=bc1;
        cout<<"pour bc1:"<<endl;
        bc1.print();
        cout<<"pour bc2:"<<endl;
        bc2.print();
        cout<<"\navec la classe WellCopyable"<<endl;
        WellCopyable wc1;
        WellCopyable wc2=wc1;
        cout<<"pour wc1:"<<endl;
        wc1.print();
        cout<<"pour wc2:"<<endl;
        wc2.print();
        /* Le code ci-dessous, s'il était décommenté, provoquerait une erreur de
         * type "error: 'NonCopyable::NonCopyable(const NonCopyable&)' is private
         * within this context" à la compilation
         */
         //cout<<"avec la classe NonCopyable"<<endl;
         //NonCopyable nc1;
         //NonCopyable nc2=nc1;
        return 0;
    }
    (chez toi, la classe Member correspondrait en réalité à ta classe D3DXVECTOR3 )
    Voici la sortie que j'obtiens
    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
     
    avec la classe BadCopyable
    pour bc1:
    	adresse de m1 0x3d2470
    	adresse de m2 0x3d26d8
    pour bc2:
    	adresse de m1 0x3d2470
    	adresse de m2 0x3d26d8
     
    avec la classe WellCopyable
    pour wc1:
    	adresse de m1 0x3d26e8
    	adresse de m2 0x3d26f8
    pour wc2:
    	adresse de m1 0x3d2708
    	adresse de m2 0x3d2718
    (il n'est pas impossible que les adresses soient différentes chez toi )
    On constate que les adresses des membres de bc1 et bc2 sont identiques, et on se rend dés lors compte que, si on venait à modifier bc1->m1, on modifierait également bc2->m1 (ou vice versa)

    Par contre, les adresses des membres de wc1 et de wc2 sont différentes.

    Cela signifie que si l'on venait à modifier wc1->m1, cela n'aurait plus la moindre répercution sur wc2

    La classe NonCopyable, enfin, est fournie juste pour t'indiquer l'erreur que tu obtiendrais à la compilation si tu décidais de rendre tes Objet_Mobile non copiables
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 13
    Par défaut
    je me suis amusé à écrire le petit code suivant
    Whooo ! Pas mal, j'avoue. Si tu as pu t'amuser aussi, c'est cool . En tout cas, merci beaucoup pour cette réponse, j'ai bien compris le principe, et je vais tester ça sous peu, je te dirais si ça a marché ! Merci encore de m'avoir consacré un peu de ton temps.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Tout cela était aussi pour te montrer l'énorme inconvénient d'utiliser des pointeurs pour les membres d'une classe.

    On pourrait aussi mettre en avant le risque, pour la classe BadCopyable de mon code, de la tentative multiple de libérer la méoire, du fait de l'appel systématique au destructeur en sortie de portée, avec tous les problèmes que cela peut engendrer

    Les pointeurs, c'est comme beaucoup d'autres concepts: ils doivent être utilisé quand c'est réellement nécessaire.

    En gros, il n'y a que trois cas génériques dans lesquels les pointeurs devraient être utilisés:
    1. Quand un type doit disposer d'une référence vers un élément de type identique (comme les structures dynamiques (pile, file, liste, arbres) créées soi même)
    2. Quand il y a une relation de "contenant à contenu" (père à enfant, responsable à responsabilité, propriétaire à propriété...) et que le contenu doit disposer d'une référence sur le contenant
    3. Quand il s'agit de pouvoir mettre en place le polymorphisme (pouvoir faire tenir dans un même conteneur des chats, des chiens et des chevaux sous le vocable "mammifères")

    Dans tous les autres cas, il est largement plus intéressant de travailler avec des membres classiques ou avec des références

    La justification du
    Pour répondre à la question, je gère des pointeurs pour plus de facilité et de lisibilité du reste du code.
    est enfin la plus mauvaise raison à l'utilisation des pointeurs que tu aurais pu trouver

    Dans ton cas, je me dis que tu pourrait trouver la justification à l'utilisation de pointeurs dans le fait que tu n'utilise pas le principe RAII (Ressouse Acquisition Is Initialisation ou, si tu préfère, l'acquisition de ressources est l'initialisation).

    Si c'est le cas, rajoute simplement un booléen pour chaque élément non initialisé, qui serait placé à faux dans le constructeur et modifié à vrai lors de l'initialisation

    Cela pourrait prendre 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
    class Objet_Mobile
    {
        public:
            Objet_Mobile():posset(false),rotset(false),tailleset(false)
            {}
            /* éventuellement */
            Objet_Mobile(const D3DXVECTOR3& pos, const D3DXVECTOR3 rot,
                         const D3DXVECTOR3 & t):position(pos),rotation(rot)
                         taille(t), posset(true), rotset(true), tailleset(true)
            {}
            /*...*/
            bool positionIsSet(){return posset;}
            bool rotationIsSet(){return rotset;}
            bool tailleIsSet(){return tailleset;}
            void setPosition(const D3DXVECTOR3 &newpos)
            {
                position=newpos;
                posset=true;
            }
            void setRotation(const D3DXVECTOR3 &newrot)
            {
                rotation=newrot;
                rotset=true;
            }
            void setTaille(const D3DXVECTOR3 &newtaille)
            {
                taille=newtaille;
                tailleset=true;
            }
        private       
            int point_de_vie;
            D3DXVECTOR3 position;
            D3DXVECTOR3 rotation;
            D3DXVECTOR3 taille;
            int index,
            int state,
            int poids;
            bool posset;
            bool rotset;
            bool tailleset;
    };
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Réponses: 12
    Dernier message: 08/03/2006, 17h27
  2. [SAP DB] Information
    Par aem_ dans le forum SAP
    Réponses: 6
    Dernier message: 07/04/2003, 22h54
  3. [PostgreSQL] Informations générales.
    Par nicox dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 11/03/2003, 09h47
  4. [PRO*C] Recherche information
    Par Anonymous dans le forum Interfaces de programmation
    Réponses: 2
    Dernier message: 04/04/2002, 17h53

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