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

SL & STL C++ Discussion :

STL - objet dans un vector/deque


Sujet :

SL & STL C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut STL - objet dans un vector/deque
    Bonjour à tous,

    mon problème doit être, je pense, assez simple, mais étant donné que je débute en c++/STL, je n'arrive pas à le résoudre.

    J'ai quelquechose comme ceci :
    la classe "objet" est composée d'un int et d'un bool.
    dans une autre classe "objet_sys", j'ai (entre autre) ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector<objet*> vect;
    et une méthode qui passe le booléen à true
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void objet::initialize() { init = true ; }
    cepandant, j'aimerai pouvoir effectuer cette opération sur tous mes objets
    c'est justement la fonction qui ne marche pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void objet_sys::init_all_obj() {
     
    for( std::vector<objet*>::iterator p = vect.begin() ; p != vect.end() ; p++)
     
        (*p)->initialize() // plante à cet instant
     
    }
    mes objets sont insérés dans le vector de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     vect.push_back(new objet(..., ...));
    A noter que je n'ai aucune erreur de compliation, même pas un warning. je travaile sous wxDev-cpp. En fait, j'ai ici juste abstrait le foctionnement de programme que je réalise. Ceci s'applique à un vecteur de sommets.

    Est ce que quelqu'un pourrait me dire ce que je fais mal ou que j'oublie de faire ?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Et bien, au feeling je dirais que tu as redéfini le destructeur de ton objet_sys pour qu'il détruise tous les objets de ton vector mais tu n'as pas défini son constructeur et son opérateur de copie.
    Donc, d'une façon ou d'une autre, tu copies ton objet_sys puis tu détruis l'original, la copie se retrouve alors avec des pointeurs fantomes sur tes objets.
    Au fait, de quelle façon est-ce que cette fonction ne marche pas?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    En fait, le programme plante et j'ai un message d'erreur de windows. Dans le rapport d'errreur, j'ai vu execption code 0xc0000005, je crois que c'est un ACCES_VIOLATION non ?

    sinon, en effet, je n'ai pas défini son opérateur de copie ( si c'est bien de "=" dont tu parles). Par contre, j'ai défini son constructeur et je n'ai pas de destructeur. Je ne détruis pas mon objet_sys. Mon main est les suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    *obj_sys = new objet_sys(3); // pour trois objets
     
    obj_sys->add(new objet(...,...)); // appelle vect.push_back(objet* o)
    obj_sys->add(new objet(...,...));
    obj_sys->add(new objet(...,...));
     
    obj_sys->init_all_obj(); // plante

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Je ne vois aucun problème avec ton code.
    Fournis un exemple minimal réduit.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    test_stl.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
    #define TEST_STL_H
    #include <cstdlib>
    #include <iostream>
    #include <vector>
    #include <string>
     
    class objet {
     
        int id;
        int v;
        std::string desc;
        static int count;
        bool init;
     
        public :
     
            objet();
            objet(int i, std::string desc_);
            void initialize();
     
    };
     
    class master_sys {
     
        std::vector<objet*> vect;
     
        public:
     
            master_sys();
            master_sys(size_t n);
            void add(objet* o);
            void init_obj();
     
    };
    test_stl.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
    #include "test_stl.h"
    int objet::count = 0;
     
    objet::objet() {
     
        id = count++;
        desc = "Desc par defaut";
        v = 0;
        init = false;
     
    }
     
     
    objet::objet(int i, std::string desc_) {
     
        id = count++;
        desc = desc_;
        v = i;
        init = false;
     
    }
     
     
     
    void objet::initialize() {
     
        init = true;
     
    }
     
     
    master_sys::master_sys() {
        using namespace std;
     
        vect.resize(1);
     
    }
     
    master_sys::master_sys(size_t n) {
     
        vect.resize(n);
     
    }
     
    void master_sys::add(objet* o) {
        using namespace std;
        vect.push_back(o);
     
    }
     
    void master_sys::init_obj() {
     
        for( std::vector<objet*>::iterator p = vect.begin(); p != vect.end(); ++p ) {
     
                (p*)->initialize();
            }
     
    }
    main.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
    #include "test_stl.h"
     
     
    int main() {
     
        master_sys *ms = new master_sys(3);
     
        ms->add(new objet(4, "Permier objet"));
        ms->add(new objet(5, "second objet"));
        ms->add(new objet(6, "trosieme objet"));
        ms->init_obj();
     
        return(EXIT_SUCCESS);
    }

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    as-tu essayé sans le resize ?
    as-tu essayé de te mettre en deboguer pas à pas dans ta fonction init_objet() ?

    Sinon, ça n'a rien à voir, mais :
    1/ Dans ton constructeur object(int, string), vu ce que tu en fais, tu peux éviter une copie de ton string en le passant par reférence constante.

    2/ Pourquoi mets-tu parfois des using namespas std dans 2 de tes fonctions ??

    3/ Non le constructeur de copie n'est pas l'opérateur d'affectation ( = ).

    4/ Il faudrait libérer tes allocation d'objets dans ton vecteur

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    ça m'étonne mais effectivement, sans les resize(), ça fonctionne parfaitement
    Juste par curiosité, pourquoi les resize() faisaient il planter le programme ?

    Merci pour le coup de pouce.

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Tes resize ne font pas planter le programme.
    C'est ton utilisation ensuite qui le fait planter.

    Une fois que tu a fait ton resize(3), ton tableau fait une taille de 3, bon ça c'est normal !!
    Mais tes 3 éléments ainsi crées sont ... NULL !!!
    Ton problème est là !

    Et toi derrière, te rajoutes 3 nouveaux éléments avec push_back.
    Donc maintenant taille = 6 !!!

    Résultat : quand tu veux initialiser tes objects, en faisant :
    (p*)->initialize();
    ben tu appliques initialize à NULL :: --> BOUMM !

    Donc, si tu veux effectivement garder ton resize(3), tu ajoutes tes éléments en faisant vect[0] = new object(3, "pinpin"); vect[1] = ... et vect[2] = ...

    Sinon, tu te passes du resize.

    @+

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Points : 256
    Points
    256
    Par défaut
    Tes resize ne font pas planter le programme.
    C'est ton utilisation ensuite qui le fait planter.

    Une fois que tu a fait ton resize(3), ton tableau fait une taille de 3, bon ça c'est normal !!
    Mais tes 3 éléments ainsi crées sont ... NULL !!!
    Ton problème est là !

    Et toi derrière, te rajoutes 3 nouveaux éléments avec push_back.
    Donc maintenant taille = 6 !!!

    Résultat : quand tu veux initialiser tes objects, en faisant :
    (p*)->initialize();
    ben tu appliques initialize à NULL :: --> BOUMM ! (c'est pour l'image... hein )

    Donc, si tu veux effectivement garder ton resize(3), tu ajoutes tes éléments en faisant vect[0] = new object(3, "pinpin"); vect[1] = ... et vect[2] = ...

    Sinon, tu te passes du resize.

    @+

  10. #10
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ton code n'est pas un exemple minimal réduit.
    Déjà, c'est sur plusieurs fichiers, donc c'est mal parti.
    Ensuite il y a une grande quantité de code qui n'a absolument rien à voir avec le problème.

    C'est quand même lourd pour les autres de jouer le rôle du débogueur...

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    16
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 16
    Points : 13
    Points
    13
    Par défaut
    Merci olive de m'avoir éclairé sur le sujet, je pensais que resize() préparait le tableau à recevoir tant d'éléments.
    Désolé loufoque, j'ai pas l'habitude de poster sur des forums de prog, je ferais plus attention la prochaine fois

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Le truc qui réserve la mémoire sans ajouter les éléments, c'est reserve, et non resize. Il n'a d'utilité qu'en terme d'optimisation, quand on sait combien d'éléments on va ajouter par push_back.

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

Discussions similaires

  1. Accès aux méthodes d'un objet dans un vector.
    Par Huruu dans le forum Débuter
    Réponses: 4
    Dernier message: 09/02/2010, 16h23
  2. suppression d'un pointeur sur un objet dans un vector
    Par Mindiell dans le forum SL & STL
    Réponses: 9
    Dernier message: 07/08/2008, 14h42
  3. Existence d'un objet dans un Vector
    Par FabaCoeur dans le forum Collection et Stream
    Réponses: 5
    Dernier message: 03/03/2008, 20h51
  4. [STL]Suppression d'un objet dans un vector
    Par cssiste dans le forum SL & STL
    Réponses: 10
    Dernier message: 19/07/2007, 14h23
  5. objets dans un vector
    Par anasama dans le forum SL & STL
    Réponses: 2
    Dernier message: 21/04/2006, 10h21

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