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 d'accès à un pointeur


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 12
    Points
    12
    Par défaut Problème d'accès à un pointeur
    Bonsoir,

    J'ai un problème depuis hier que je n'arrive pas à résoudre, j'ai essayé plusieurs solutions sans succès
    Est-il possible d'accéder à un pointeur d'une classe englobante depuis une structure imbriquée ? Voici une partie de mon code pour mieux comprendre :

    La classe Mesh :
    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
    class QOpenGLFunctions;
     
    class Mesh
    {
     
    public:
        Mesh();
        ~Mesh();
     
    private:
        QOpenGLFunctions* m_funcs;
     
        struct MeshEntry
        {
            MeshEntry();
            ~MeshEntry();
     
            void Init(const vector<Vertex>& Vertices, const vector<unsigned int>& Indices);
        };
     
    };
    La fonction Init de la structure MeshEntry où je fais appel au pointeur voulu (m_funcs) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Mesh::MeshEntry::Init(const vector<Vertex>& Vertices, const vector<unsigned int>& Indices)
    {
        m_funcs->glGenBuffers(...); // Erreur C2327 / C2065 / C2227
    }
    Le constructeur de la classe Mesh (il n'y a pas de problème à ce niveau là, j'utilise ce bout de code dans d'autres classes)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Mesh::Mesh() : m_funcs(0)
    {
        QOpenGLContext* context = QOpenGLContext::currentContext();
     
        Q_ASSERT(context);
     
        m_funcs = context->functions();
        m_funcs->initializeOpenGLFunctions();
    }
    Je peux utiliser le pointeur m_funcs dans les méthodes de la classe Mesh mais dès que je l'utilise à l'intérieur d'une fonction de la structure MeshEntry, le compilateur m'envoie 3 erreurs :

    C2327 : "Mesh::m_funcs" n'est pas un nom de type, un membre static, ni un énumérateur
    C2065 : "m_funcs" : identificateur non déclaré
    C2227 : la partie gauche de "->glGenBuffers" doit pointer vers un type class/struct/union/générique

    Existe-t-il une solution pour accéder à ce pointeur depuis cette structure ?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    ton compilateur a bien raison, m_func n'a strictement rien à voir avec MEshEntry.
    Le fait que tu ais déclaré MeshEntry dans Mesh est totalement anecdotique et n'y change rien.
    Si tu veux utiliser m_func, qui est membre de Mesh, il te faut une instance de Mesh.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Merci pour ta réponse.

    Je viens d'essayer ta solution, il n'y a plus d'erreur au niveau du pointeur mais une autre est apparue :

    C2582 : 'operator =' fonction non disponible dans 'Mesh::MeshEntry'

    Je comprend l'erreur mais je n'arrive pas à implémenter une solution qui marche... voici ce que j'ai modifié :

    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
    class Mesh
    {
     
    public:
        Mesh();
        ~Mesh();
     
    private:
        QOpenGLFunctions* m_funcs;
     
        struct MeshEntry
        {
            MeshEntry(Mesh& mesh);
            ~MeshEntry();
     
            void Init(const vector<Vertex>& Vertices, const vector<unsigned int>& Indices);
            void operator=(const MeshEntry& me);
     
            Mesh& m_mesh;
        };
     
    };
    Le constructeur de MeshEntry :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Mesh::MeshEntry::MeshEntry(Mesh& mesh) : m_mesh(mesh)
    {
     
    }
    La fonction Init :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Mesh::MeshEntry::Init(const vector<Vertex>& Vertices, const vector<unsigned int>& Indices)
    {
        m_mesh.m_funcs->glGenBuffers(...);
    }
    Et voila ce que je n'arrive pas à implémenter, je ne sais pas même si c'est bien ce que demande le compilateur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Mesh::MeshEntry::operator=(const MeshEntry& me)
    {
        // ...
    }

  4. #4
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Pas tout à fait, le retour doit être une référence sur la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Mesh::MeshEntry & operator=(const MeshEntry& me);
    Je te laisse consulter la FAQ Quand dois-je définir l'opérateur d'affectation ? ainsi que ses liens annexes.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    J'avais déjà regardé cette section de la FAQ, mais je me demande pourquoi je dois utiliser la surcharge de l'opérateur d'affectation pour simplement faire référence à une classe afin d'utiliser un de ses membres, je suis perdu... De plus, la solution apporté par la FAQ n'est pas adaptée à mon problème, si ?

    Edit : Je viens de tomber sur ça : http://stackoverflow.com/questions/6...-c-inner-class

    La première solution, c'est de passer en paramètre une référence de la classe Mesh aux fonctions qui en ont besoin mais dans mon cas elle ne peut pas fonctionner car j'ai besoin d'utiliser ce pointeur dans le destructeur de MeshEntry
    Et ils ne mentionnent pas l'utilisation de l'opérateur d'affection pour l'autre solution (celle que je viens d'essayer).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Parce qu'une référence ne tolère pas une valeur "par défaut", il faut obligatoirement lui en fournir une de valide, ce qu'est incapable de faire l'opérateur = fourni par défaut. Il faut donc le définir toi-même en prenant soin d'initialiser ta référence correctement (il en est d'ailleurs de même pour le constructeur par copie).
    Ou si tu n'as pas envie de t'embêter à le redéfinir, tu peux utiliser un std::reference_wraper.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    Bon apparemment mon problème est réglé, la solution de la FAQ fonctionne bien, merci Winjerome pour l'explication, je comprend mieux d'où vient le problème maintenant.

    Le programme fonctionne bien mais lorsque je le quitte, j'ai le droit à l'erreur suivante :

    Le programme s'est terminé subitement. error code : -1073741819

    Ce code correspond apparemment à un dépassement de pile (stack overflow). Après quelques recherches, j'ai trouvé que c'était à cause du destructeur de la structure MeshEntry. Lorsque que le corps du destructeur est vide, il n'y a plus d'erreur.

    Ce n'est pas à cause de l'instruction delete présente dans le destructeur, car même si je l'enlève, j'ai quand même le droit au dépassement de pile. Pour que l'erreur disparaisse, faut que le destructeur soit complètement vide...

    Une idée ?

    Je vous mets à disposition la classe complète, elle est loin d'être finalisée, c'est une base pour charger un modèle 3D avec la bibliothèque Assimp.

    • mesh.h :
      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
      #ifndef MESH_H
      #define MESH_H
       
      #include <map>
      #include <vector>
      #include <string>
       
      #include "assimp/Importer.hpp"
      #include "assimp/scene.h"
      #include "assimp/postprocess.h"
       
      #include "../helpers/util.h"
      #include "../helpers/math_3d.h"
       
      #include <qopengl.h>
       
      using namespace std;
       
      struct Vertex
      {
          Vector3f m_pos;
          Vector2f m_tex;
          Vector3f m_normal;
       
          Vertex() {}
       
          Vertex(const Vector3f& pos, const Vector2f& tex, const Vector3f& normal)
          {
              m_pos    = pos;
              m_tex    = tex;
              m_normal = normal;
          }
      };
       
      class Texture;
      class QOpenGLFunctions;
       
      class Mesh
      {
       
      public:
          Mesh();
          ~Mesh();
       
          void Init();
          void LoadMesh(const string& Filename);
          void Render();
       
      private:
          void InitFromScene(const aiScene* pScene, const string& Filename);
          bool InitMaterials(const aiScene* pScene, const string& Filename);
          void InitMesh(unsigned int Index, const aiMesh* paiMesh);
          void Clear();
       
          #define INVALID_MATERIAL 0xFFFFFFFF
       
          QOpenGLFunctions* m_funcs;
       
          struct MeshEntry
          {
              MeshEntry();
              MeshEntry(Mesh *mesh);
              MeshEntry(const MeshEntry& other);
              ~MeshEntry();
       
              void Init(const vector<Vertex>& Vertices, const vector<unsigned int>& Indices);
              Mesh::MeshEntry& operator=(const MeshEntry& other);
       
              GLuint VB;
              GLuint IB;
       
              unsigned int NumIndices;
              unsigned int MaterialIndex;
       
              Mesh* m_mesh;
          };
       
          vector<MeshEntry> m_Entries;
          vector<Texture*>  m_Textures;
       
      };
       
      #endif // MESH_H
    • mesh.cpp :
      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
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
       
       
          #include "mesh.h"
          #include "assert.h"
       
          #include "../materials/texture.h"
       
          #include <QDebug>
          #include <QOpenGLContext>
          #include <QOpenGLFunctions>
       
          Mesh::Mesh() : m_funcs(0) {}
       
          Mesh::~Mesh()
          {
              Clear();
          }
       
          Mesh::MeshEntry::MeshEntry() {}
       
          Mesh::MeshEntry::MeshEntry(Mesh* mesh) : m_mesh(mesh)
          {
              VB = INVALID_OGL_VALUE;
              IB = INVALID_OGL_VALUE;
       
              NumIndices    = 0;
              MaterialIndex = INVALID_MATERIAL;
          }
       
          Mesh::MeshEntry::MeshEntry(const MeshEntry& other)
          {
              if(other.m_mesh)
                  this->m_mesh = new Mesh(*other.m_mesh);
              else
                  this->m_mesh = NULL;
          }
       
          Mesh::MeshEntry::~MeshEntry()
          {
              if(VB != INVALID_OGL_VALUE)
                  m_mesh->m_funcs->glDeleteBuffers(1, &VB);
       
              if(IB != INVALID_OGL_VALUE)
                  m_mesh->m_funcs->glDeleteBuffers(1, &IB);
       
              delete this->m_mesh;
          }
       
          Mesh::MeshEntry& Mesh::MeshEntry::operator=(const MeshEntry& other)
          {
              Mesh::MeshEntry tmp(other);
       
              std::swap(tmp.m_mesh, this->m_mesh);
       
              return *this;
          }
       
          void Mesh::MeshEntry::Init(const vector<Vertex>& Vertices, const vector<unsigned int>& Indices)
          {
              NumIndices = static_cast<unsigned int>(Indices.size());
       
              m_mesh->m_funcs->glGenBuffers(1, &VB);
              m_mesh->m_funcs->glBindBuffer(GL_ARRAY_BUFFER, VB);
              m_mesh->m_funcs->glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * Vertices.size(), &Vertices[0], GL_STATIC_DRAW);
       
              m_mesh->m_funcs->glGenBuffers(1, &IB);
              m_mesh->m_funcs->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IB);
              m_mesh->m_funcs->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * NumIndices, &Indices[0], GL_STATIC_DRAW);
          }
       
          void Mesh::Clear()
          {
              for(unsigned int i = 0; i < m_Textures.size(); i++)
              {
                  SAFE_DELETE(m_Textures[i]);
              }
          }
       
          void Mesh::Init()
          {
              QOpenGLContext* context = QOpenGLContext::currentContext();
       
              Q_ASSERT(context);
       
              m_funcs = context->functions();
              m_funcs->initializeOpenGLFunctions();
          }
       
          void Mesh::LoadMesh(const string& Filename)
          {
              Clear();
       
              Assimp::Importer Importer;
       
              const aiScene* pScene = Importer.ReadFile(Filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
       
              if(pScene)
                  InitFromScene(pScene, Filename);
              else
                  qDebug() << "Error parsing : " << Filename.c_str() << " -> " << Importer.GetErrorString() << endl;
          }
       
          void Mesh::InitFromScene(const aiScene* pScene, const string& Filename)
          {
              m_Entries.resize(pScene->mNumMeshes);
              m_Textures.resize(pScene->mNumMaterials);
       
              for(unsigned int i = 0; i < m_Entries.size(); i++)
              {
                  const aiMesh* paiMesh = pScene->mMeshes[i];
                  InitMesh(i, paiMesh);
              }
       
              InitMaterials(pScene, Filename);
          }
       
          bool Mesh::InitMaterials(const aiScene* pScene, const string& Filename)
          {
              Q_UNUSED(pScene);
              Q_UNUSED(Filename);
       
              return true;
          }
       
          void Mesh::InitMesh(unsigned int Index, const aiMesh* paiMesh)
          {
              Q_UNUSED(Index);
              Q_UNUSED(paiMesh);
          }
       
          void Mesh::Render()
          {
       
          }

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 518
    Points
    41 518
    Par défaut
    -1073741819 c'est 0xC0000005, alias EXCEPTION_ACCESS_VIOLATION.
    Ce n'est pas une débordement de pile (EXCEPTION_STACK_OVERFLOW, 0xC00000FD, -1073741571 en décimal), c'est un déréférencement de pointeur invalide.
    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.

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

    Informations professionnelles :
    Activité : aucun

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

    C'est normal :

    Dans le destructeur de Mesh, m_entries va être automatiquement détruit, ainsi que toutes les MeshEntry qu'il contient.

    Mais dans le destructeur de MeshEntry, tu essayes de libérer la mémoire allouée au pointeur sur Mesh qui n'est rien d'autre... que le mesh qui est occupé à être détruit.

    Tu essayes donc de détruire quelque chose qui est, justement, en cours de destruction

    A moins, bien sur, qu'il ne s'agisse d'un autre Mesh, mais, étant donné que tu travailles sur un graphe qui reviendra, tôt ou tard, sur le mesh d'origine, le résultat sera le même

    La solution consiste à disposer d'une collection qui regroupe l'ensemble des mesh "quelque part", et à ne détruire ceux-ci que quand tu retires un mesh de cette collection.

    De cette manière MeshEntry se contente de faire le lien entre les différents mesh, sans avoir à s'inquiéter de les détruire
    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 à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    @koala01 > Je n'ai pas bien compris ta solution. Il faudrait que j'utilise un pointeur intelligent pour que la destruction du pointeur soit automatique, c'est bien ça ?

    Le problème c'est que j'utilise quand même le pointeur m_mesh dans le destructeur de MeshEntry afin d'avoir accès à la fonction glDeleteBuffers() pour supprimer les VBOs et IBOs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Mesh::MeshEntry::~MeshEntry()
    {
        // delete this->m_mesh;
    
        if(VB != INVALID_OGL_VALUE)
            m_mesh->m_funcs->glDeleteBuffers(1, &VB);
    
        if(IB != INVALID_OGL_VALUE)
            m_mesh->m_funcs->glDeleteBuffers(1, &IB);
    }
    Donc en fait je ne peux pas utiliser le pointeur m_mesh dans le destructeur de MeshEntry... ça bloque carrement ce que je veux faire

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par Hardware31 Voir le message
    @koala01 > Je n'ai pas bien compris ta solution. Il faudrait que j'utilise un pointeur intelligent pour que la destruction du pointeur soit automatique, c'est bien ça ?
    L'utilisation des pointeurs intelligents serait effectivement un plus, mais ce n'est malgré tout pas ce que j'ai voulu dire.

    Ce que j'ai voulu dire, c'est que tu devrais maintenir tes mesh "à part", par exemple sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<Mesh*> meshes;
    C'est quand tu ajoutes un mesh à ce tableau que tu invoques new et quand tu le supprimes de ce tableau que tu
    invoques delete.

    D'un autre coté, maintiendrait une liste de MeshEntry. Cela pourrait prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<MeshEntry> entries;
    Quand tu supprimes un mesh du premier tableau, tu supprimes également toutes les entry qui y font référence dans le deuxième.

    Tu peux avoir dans Mesh un tableau de MeshEntry pour la facilité, ce sont toutes les entrées qui "partent" d'un mesh particulier.

    Tu peux avoir au niveau de MeshEntry un pointeur vers le mesh "terminal", c'est l'entrée qui fait la liaison entre deux meshes.

    Seulement, tu n'invoques pas delete sur ce pointeur.

    Parce que si, dans ton entrée, tu essayes de détruire le mesh "terminal", tu vas détruire récursivement toute une série d'entrée, et les mesh terminaux de ceux-ci.

    Il y a donc un grand risque pour que l'un des mesh terminaux que tu essayeras de détruire soit, justement, un mesh qui a déjà été détruit. Et c'est ce qui occasionne ton problème.

    Un petit shéma pour comprendre: Mettons que a est un mesh dont une des entrée fait référence au mesh b dont une des entrées fait référence au mesh c, dont une des entrées fait référence (ainsi de suite jusqu'à)... h dont une des entrées fait référence au mesh a.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    a --> b --> c --> d
    ^                 |
    |                 \/
    h <-- g <-- f <-- e
    Avec le code que tu présentes, si tu détruis a, l'entrée qui fait référence à b détuira b, qui détruira c qui détruira d détruira e qui détruira f, qui détruira g qui détruira h qui essayera de détruire a... qui est justement déjà détruit.

    Pas cool, hein ?
    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

  12. #12
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Juillet 2013
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2013
    Messages : 15
    Points : 12
    Points
    12
    Par défaut
    J'ai enfin réussi à résoudre mon problème en réorganisant un peu la classe pour éviter l'utilisation du pointeur m_mesh qui n'est pas vraiment pratique et même limite dangereux

    En fait l'erreur que j'ai fait c'est de vouloir utiliser directement les fonctions le l'API d'OpenGL pour gérer les buffers (Vertex Buffer et Index Buffer) des mesh entries alors que Qt fournit un classe qui gère ça parfaitement : QOpenGLBuffer
    Je n'ai plus besoin du pointeur permettant de lier la classe Mesh avec la structure MeshEntry donc plus besoin de surcharger l'opérateur d'affectation et de rajouter explicitement un constructeur de copie.

    Mon problème est assez spécifique mais je vous donne quand même, pour ceux qui sont intéressés, le code que j'ai modifié afin de résoudre ce problème :

    La structure MeshEntry :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    struct MeshEntry
    {
        MeshEntry();
        ~MeshEntry();
     
        void Init(const QVector<Vertex>& Vertices, const QVector<unsigned int>& Indices);
     
        QOpenGLBuffer m_vertexPositionBuffer;
        QOpenGLBuffer m_vertexIndexBuffer;
     
        unsigned int NumIndices;
        unsigned int MaterialIndex;
    };
    Le constructeur par défaut de MeshEntry :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Mesh::MeshEntry::MeshEntry()
        : m_vertexPositionBuffer(QOpenGLBuffer::VertexBuffer),
          m_vertexIndexBuffer(QOpenGLBuffer::IndexBuffer),
          NumIndices(0),
          MaterialIndex(INVALID_MATERIAL)
    {}
    Le destructeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Mesh::MeshEntry::~MeshEntry()
    {
        m_vertexPositionBuffer.destroy();
        m_vertexIndexBuffer.destroy();
    }
    La fonction Mesh:MeshEntry::Init()

    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
    void Mesh::MeshEntry::Init(const QVector<Vertex> &Vertices, const QVector<unsigned int> &Indices)
    {
        NumIndices = static_cast<unsigned int>(Indices.size());
     
        m_vertexPositionBuffer.create();
        m_vertexPositionBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
        m_vertexPositionBuffer.bind();
        m_vertexPositionBuffer.allocate(Vertices.constData(), Vertices.size() * sizeof(Vertex));
        m_vertexPositionBuffer.release();
     
        m_vertexIndexBuffer.create();
        m_vertexIndexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
        m_vertexIndexBuffer.bind();
        m_vertexIndexBuffer.allocate(Indices.constData(), NumIndices * sizeof(unsigned int));
        m_vertexIndexBuffer.release();
    }
    Merci à vous en tout cas de m'avoir aider, je comprends mieux le fonctionnement des classes englobantes/imbriquées.

    Cette partie de mon projet est terminée, je vous ai fait quelques screens pour vous montrer le résultat, enfin quelque chose de concret, parce que c'est bien beau du code mais faut que ça serve bien à quelque chose ^^





    Encore merci à tous et bonne continuation !

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

Discussions similaires

  1. Problème d'accès à un tableau de pointeur
    Par gronaze dans le forum C++
    Réponses: 2
    Dernier message: 24/11/2011, 10h02
  2. [ADO] [MSACCESS] Problème d'accès à une table nommée OF
    Par FredRaid dans le forum Bases de données
    Réponses: 3
    Dernier message: 15/02/2005, 17h22
  3. Problème d'accès à une DB
    Par Mvu dans le forum ASP
    Réponses: 4
    Dernier message: 04/01/2005, 11h36
  4. [TOMCAT] JSP problème d'accès aux méthodes d'une classes
    Par gunnm dans le forum Tomcat et TomEE
    Réponses: 3
    Dernier message: 22/05/2004, 14h02
  5. problème d'acces concurentiel à un fichier
    Par Theoden dans le forum MFC
    Réponses: 2
    Dernier message: 04/03/2004, 09h49

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