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 :

objets anonymes dans un vector<> (3D)


Sujet :

C++

  1. #1
    Membre régulier Avatar de lightbulb
    Homme Profil pro
    Inscrit en
    Septembre 2008
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 108
    Points : 96
    Points
    96
    Par défaut objets anonymes dans un vector<> (3D)
    Bonjour à tous,
    je travail actuellement sur un moteur 3D directX10 mais mon problème vient d'une notion de C++ qu'il doit me manquer.

    J'essaie de permettre à l'utilisateur de créer autant d'instances d'un objet(mesh) qu'il le souhaite, la solution qui m'est venue en tête de prime abord est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         vector<sphere> mSph;
         mSph.push_back(sphere()); //a chaque appui sur une touche
         mSph.back().init(); //initialise les propriétés de ma sphere
    Ce code fonctionne uniquement si dans le destructeur de ma classe sphere
    je commente le code qui permet de libérer le vertex buffer, l'index buffer et le textureBuffer, dans le cas contraire j'ai un erreur d'accès en mémoire dès le push_back de mon objet anonyme dans le vecteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	SAFE_RELEASE(mVB);
    	SAFE_RELEASE(mIB);
    	SAFE_RELEASE(textureBuffer);
    Si je commente ces lignes j'ai un gros problème de fuite mémoire au véritable moment ou j'ai besoin de libérer ces objets car le destructeur ne sert plus à rien et des Mo de texture, de VB et d'IB s'empilent dans la mémoire sans être libérés. Néanmoins une fois ces lignes commentés le programme fonctionne tout à fait correctement et crée les sphères dynamiquement.

    J'aimerais savoir pourquoi le destructeur est-il appelé à l'instanciation?
    De plus le SAFE_RELEASE est sensé prévenir contre les risques d'accès en mémoire puisque le release n'est réalisé que si l'objet existe réellement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Exception non gérée à 0x012ff911 dans x.exe*: 0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0xcccccccc.
    Merci par avance !

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Fait voir ta classe sphère mais je soupçonne qu'elle contient un pointeur mais que tu n'as pas défini de constructeur de copie.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre régulier Avatar de lightbulb
    Homme Profil pro
    Inscrit en
    Septembre 2008
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 108
    Points : 96
    Points
    96
    Par défaut
    C'est bon j'ai enfin compris !!!
    Effectivement en C++ afin de manipuler des pointeurs instanciés dans un objet que l'on place dans un vecteur il faut déclarer notre vecteur comme pointeur. L'objet anonyme est également créé sous forme de pointeur et l'accès en mémoire au niveau du destructeur marche désormais parfaitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
         vector<Sphere*> mSph;
         mSph.push_back(new Sphere());
    Et bien sure comme c'est du directX on oublie par de détruire les objets lors de la destruction du device :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	for(int i=0;i<mSph.size();i++) //on vide le tableau
    	{
    		mSph.at(i)->~Sphere();
    	}
    Problème résolu, bonne continuation à tous !

  4. #4
    Membre régulier Avatar de lightbulb
    Homme Profil pro
    Inscrit en
    Septembre 2008
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 108
    Points : 96
    Points
    96
    Par défaut
    Effectivement ma classe sphere contient des pointeurs dont

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	ID3D10Buffer* mVB;
    	ID3D10Buffer* mIB;
    qui sont libérés lors de la destruction de l'objet.

    Je n'ai effectivement pas fait de constructeur de copie, c'est vrai que j'ai trouvé une solution mais peut être que ce n'est pas la plus adaptée ou la plus optimale, pourrais tu me donner ta solution alternative avec un constructeur de copie?

  5. #5
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Non, problème non résolu.

    Si ca marche, c'est car un vecteur copie les objets qu'il manipule. En ne définissant pas de constructeur de copie, le C++ en génére un pour toi qui fait une copie bit à bit de l'objet. En copiant un objet qui contient un pointeur, tu te retrouves avec deux objets, chacun contenant un pointeur vers LA MEME adresse. Dès la destruction d'un objet (en supposant que tu libères bien la mémoire), le 2eme objet pointe vers une adresse NON NUL mais NON VALIDE. Bref, dès que tu tentes d'appeler une fonction dessus, boom, ca explose, sagfault.

    Solution; définir un constructeur de copie ET un operateur d'affectation (bien que dans ton cas, ce dernier ne serve pas, ils vont toujours ensemble)

    En manipulant des pointeurs, tu évites les problèmes car tu copies des pointeurs, ce qui évite le problème ci dessus donc le bug, mais ca ne le résout par pour autant, il reste latent.

    Enfin, NE JAMAIS APPELER LE DESTRUCTEUR DIRECTEMENT (sauf un cas particulier, placement new, mais tu en es loin encore). C'est pas ton rôle, c'est celui de l'operateur delete. Si tu veux détruire un objet alloué avec new, tu fais un delete sur un pointeur représentant l'objet.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  6. #6
    Membre régulier Avatar de lightbulb
    Homme Profil pro
    Inscrit en
    Septembre 2008
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 108
    Points : 96
    Points
    96
    Par défaut
    Merci beaucoup je vais me pencher sur le constructeur de copie alors, question : si je fais un vector de pointeur pourquoi est ce que le problème reste latent? qu'est ce qui peut se passer?

  7. #7
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Citation Envoyé par lightbulb Voir le message
    Merci beaucoup je vais me pencher sur le constructeur de copie alors, question : si je fais un vector de pointeur pourquoi est ce que le problème reste latent? qu'est ce qui peut se passer?
    Dès qu'il y aura copie d'un objet (à cause du passe à une fonction ou pour une autre raison) ou affectation entre deux objets puis destruction de l'un des deux: boom.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  8. #8
    Membre régulier Avatar de lightbulb
    Homme Profil pro
    Inscrit en
    Septembre 2008
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 108
    Points : 96
    Points
    96
    Par défaut
    Autre chose la c'est vrai j'aurais pas du appeler le destructeur j'ai remplacé par delete mais dans d'autres cas j'ai des objets statiques qui contiennent des objets dynamiques.
    Je ne peut pas faire de delete sur un objet statique donc j'appelle le destructeur pour nettoyer les références dynamiques à l'intérieur de l'objet sinon DX me sort que j'ai pas tout nettoyé !! Selon toi je devrais me créer une méthode destroy dans laquelle je nettoie tout et l'appeler au lieu d'appeler le destructeur directement? Je ne savais pas que c'était prohibé désolé

  9. #9
    Membre éprouvé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Points : 1 241
    Points
    1 241
    Par défaut
    Le destructeur d'un objet alloué de manière static (ou plutôt sur la pile) est appelé directement à la sortie du bloque où cet objet a été créé. Tu n'as donc pas besoin de l'appeler, c'est implicite dans ce cas précis.
    Par contre dans ton destructeur dois bien libérer de manière explicite (delete ou delete[]) toute les objets dynamique.

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

Discussions similaires

  1. Réponses: 21
    Dernier message: 03/06/2010, 18h26
  2. Pb liberation d'objets contenu dans un Vector
    Par pcouas dans le forum Langage
    Réponses: 1
    Dernier message: 11/06/2008, 23h00
  3. Polymorphisme et objets stockés dans un vector
    Par sylverspoon dans le forum Langage
    Réponses: 5
    Dernier message: 25/05/2007, 21h43
  4. objets dans un vector
    Par anasama dans le forum SL & STL
    Réponses: 2
    Dernier message: 21/04/2006, 10h21
  5. objets différents dans un même vector...
    Par Empty_body dans le forum Langage
    Réponses: 7
    Dernier message: 07/01/2006, 18h20

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