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 :

push_back et .. écran bleu + reboot (comme au bon vieux temps)


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Points : 121
    Points
    121
    Par défaut push_back et .. écran bleu + reboot (comme au bon vieux temps)
    C'est bien la première fois que j'ai un souci avec un std :: vector !!

    J'ai une classe K3D_Tree comportant en données membres
    un std :: vector<K3D_Leaf*> trLeafs et un std :: vector<K3D_Branch*> trBranchs

    K3D_Leaf et K3D_Branch sont des classes, je stocke donc les pointeurs.

    Je n'ai aucun souci avec les K3D_Branch en revanche, ça plante direct à l'exécution dès que je veux insérer un malheureux K3D_Leaf.

    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
     
        // Et maintenant c'est au tour du feuillage
        for (unsigned int i=0; i< this->trBranchs.size(); ++i)
        {
            K3D_Branch* branch = this->trBranchs.at(i);
     
            // On parcourt toutes les branches et seules celles aux deux derniers niveaux nous interesse
            if (branch->brLevel >= this->trMaxLevel-1)
            {
                // On fait deux feuilles par branches // <= Pour l'instant qu'une
                K3D_Leaf* bLeaf = new K3D_Leaf;
                bLeaf->create(branch);
               // this->trLeafs.push_back(bLeaf); //<= OUUU PAS BIEN :D!!
            }
        }
    Quelques explications .. Les branches sont générées et placées dans le vector adéquat, sans soucis, ça marche niveau rendu à lexécution.
    Pour le feuillage, j'en mets que sur les branches extérieures à l'arbre, d'où ma boucle. Elles sont repérées par leur brLevel
    J'instancie un pointeur d'objet de K3D_Leaf, je charge et calcule toutes les données membres de K3D_Leaf à l'aide de create() (j'ai vérifié, les valeurs sont correctes, pas de division par zéro etc ..).

    Quand j'essaie de mettre mon objet dans le tableau trLeafs, ça plante totalement, je n'arrive meme pas à mettre un try/ catch dessus car l'ordi reboot !!

    Peut-il arriver qu'un push_back() échoue ?

    J'ai des soupçons sur OpenGL, je sais que faire 2 glDisable() de suite par exemple peut provoquer des erreurs subtiles mais le reboot n'intervient que lorsque cette ligne n'est plus en commentaire (. D'habitude, ça survient n'importe quand avec ce genre d'erreurs (hélas)

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Pourrais tu nous donner le code de K3D_Branch et K3D_leaf

    Y a-t-il une base commune à ces deux classes
    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

  3. #3
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    les conteneurs de la STL ne sont en général pas "faits" pour contenir des pointeurs. Utilises plutôt boost::ptr_vector.

    Je pense également comme Koala que ton problème vient principalement du code de ta classe, je pencherais vers ton copy constructeur, cependant je peux me tromper.

    Est-ce que tu peux tester un push_back d'un K3D_Leaf non pointeur (dans un contenur d'objets statiques bien entendu, juste pour tester) ? Est-ce que ça compile ? Est-ce que ça fonctionne ?

    Sinon, si tu trouves toujours pas, sans le code de tes classes on va pas pouvoir t'aider beaucoup plus

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Points : 121
    Points
    121
    Par défaut
    J'ai changé le std :: vector<K3D_Leaf*> en simple pointeur K3D_Leaf* et tout marche
    au lieu d'écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    K3D_Leaf* pLeaf = new K3D_Leaf;
    /* code*/
    this->trLeafs.push_back(pLeaf);
    j'écris :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    this->trLeafs = new trLeafs[36];  // Il y a 36 feuilles dans mon exemple
    K3D_Leaf* pLeaf = new K3D_Leaf;
    /* code */
     
     
    edit :
    Ah ben ... avec std :: vector<K3D_Leaf>, ça marche aussi ... 
    Et toujours pas avec les pointeurs ... Bon pas grave :mouarf:
    this->trLeafs[counter] = *pLeaf;
    counter étant incrémenté bien entendu.
    Le code moche quoi ... Super lol


    Non rien de commun entre les branches et les feuilles. Ces dernières ont juste besoin de savoir à quelles coordonnées sont les branches + taille etc.. Le paramètre passé dans create() sert juste à ça.


    Voici la fonction create ...

    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
     
    void K3D_Leaf :: create(K3D_Branch* branch)
    {
        // On récupère la direction de la branche et (ses coordonnées)
        Vecteur3D<float> branchDirection = branch->brForward;
        Vecteur3D<float> branchLPosition = branch->brLCenter;
        Vecteur3D<float> branchHPosition = branch->brHCenter;
        float branchLRay = branch->brLRay;
        float branchHRay = branch->brHRay;
     
     
        // On place la feuille quelque part sur la branche (pas aux extrémités)
        float coef = getRandom(0.2f,0.8f);
        this->lePosition = branchLPosition*coef + branchHPosition*(1.0f-coef);
     
        // On tient compte du cylindre
        // Rayon du cylindre au point choisi
        float branchLeafRay = branchLRay*coef + branchHRay*(1.0f-coef);
     
        // Choix d'un angle de rotation / cylindre (il vaut zéro avec l'axe OX dans le plan XOY)
        this->leAlpha = getRandom(-PI,PI);
     
        // On en déduit précisemment la place de la feuille sur la branche (mm principe que pour la branche)
        this->lePosition[0] += branchLeafRay*sin(this->leAlpha);
        this->lePosition[2] += branchLeafRay*cos(this->leAlpha);
     
        // Pour la direction, on suppose que la feuille a plus tendance à "descendre"
        // On va combiner un vecteur aléatoire avec un vecteur -j
        Vecteur3D<float> randomForward(getRandom(-1.0f,1.0f),getRandom(-1.0f,1.0f),getRandom(-1.0f,1.0f));
        Vecteur3D<float> oppJ(0.0f,-1.0f,0.0f);
     
        this->leForward = (randomForward + oppJ)*0.5f;
     
        // Attention au signe de l'abscisse et la profondeur.
        // si Alpha est entre -PI/2 et PI/2, x doit être positif sinon la feuille "rentre" dans la branche
        // Idem avec z si alpha est entre 0 et PI
        if (this->leAlpha > -PI/2 && this->leAlpha < +PI/2)
            this->leForward[0] = Max(-this->leForward[0],this->leForward[0]);
        else
            this->leForward[0] = Min(-this->leForward[0],this->leForward[0]);
     
        if (this->leAlpha > 0)
            this->leForward[2] = Max(-this->leForward[2],this->leForward[2]);
        else
            this->leForward[2] = Min(-this->leForward[2],this->leForward[2]);
     
        this->leForward.normalize();
     
        // Maintenant, on s'occupe de l'autre direction
        // Il est orthogonal à leForward mais sans composant y
        // Attention au zéro !!
        if (Max(this->leForward[0],-this->leForward[0]) > std::numeric_limits<float> :: epsilon())
            this->leStraffing = Vecteur3D<float>(-this->leForward[2]/this->leForward[0],0.0f,1.0f);
        else
        {
            if (this->leAlpha > 0 )
                this->leStraffing = Vecteur3D<float>(0.0f,0.0f,1.0f);
            else
                this->leStraffing = Vecteur3D<float>(0.0f,0.0f,-1.0f);
        }
     
        this->leStraffing.normalize();
    }
    Il n'y a a aucun pointeur dans la classe K3D_Leaf, ni dans les objets membres
    (même un passage par valeur devrait fonctionner )

    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
     
    // Classe pour les feuilles
    struct K3D_Leaf
    {
        // Données membres
        Vecteur3D<float> lePosition;
        Vecteur3D<float> leForward;     // Vecteur normé, indiquant la direction de la feuille
        Vecteur3D<float> leStraffing;   // Vecteur normé, indiquant la "largeur", othogonale à forward et // OY
        Color leColor;      // Pour l'automne par exemple !
        float leAlpha;      // Inclinaison par rapport à la branche de soutien
        float leScale;      // Pour ajuster la taille des feuilles
     
        // Constructeur
        K3D_Leaf();
        ~K3D_Leaf();
     
        // Fonctions membres
        void create(K3D_Branch*);
        void draw();
    };

    Edit :
    Oui, ça fonctionne sans le pointeur avec un std :: vector
    Pas besoin de copy constructor, y'a pas de pointeur dans la classe K3D_Leaf !

  5. #5
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Euh... Il se passe quoi si tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    K3D_Leaf* bLeaf = new K3D_Leaf();
    bLeaf->create(branch);
    trLeafs.push_back(bLeaf);
    ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Points : 121
    Points
    121
    Par défaut
    Ca plante lamentablement ... Sauf si evidemment je mets le push_back en commentaire.

    Par contre avec std :: vector<K3D_Leaf> trLeafs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    this->trLeafs.push_back(K3D_Leaf()); <= je le mets direct dans le vector
    this->trLeafs.back().create(branch);
    Ca c'est OK

    Bah tant pis je reste comme, ca me fera un truc en moins à desallouer
    Merci pour vos posts en tt cas !!

  7. #7
    Membre confirmé
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Points : 588
    Points
    588
    Par défaut
    Content que tu sois passé par un objet statique, si tu n'as pas besoin d'un pointeur, n'en utilises pas !

    Sinon, je te conseillerais plutôt de créer ton objet, d'appeller sa méthode create et ensuite seulement de l'insérer dans ton vector.

    Là tu fais un appel à back() pour rien.

Discussions similaires

  1. Réponses: 19
    Dernier message: 30/05/2015, 14h26
  2. Ouvrir deux fenetres comme au bon vieux temps
    Par Yepazix dans le forum Général Conception Web
    Réponses: 5
    Dernier message: 23/04/2013, 15h43
  3. Réponses: 5
    Dernier message: 18/03/2007, 18h12
  4. plantage windows écran bleu !
    Par benoit70 dans le forum MFC
    Réponses: 14
    Dernier message: 06/10/2005, 04h54
  5. écran bleu windows NT
    Par le_ben dans le forum Windows Serveur
    Réponses: 7
    Dernier message: 18/05/2005, 16h23

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