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 :

Utilisation de vector de structure en C++


Sujet :

C++

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par d�faut Utilisation de vector de structure en C++
    Salut � tous !!!
    Voici le d�fi :
    J'ai une structure de donn�es :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    struct Links
    {
    	AtomBase &Atome;
    	int Type;
    };
    et j'ai une classe qui poss�de un attribut vector d�finit comme cela :
    Dans cette m�me classe, existe une fonction permettant d'ajouter un nouvel �l�ment Links dans l'attribut vector :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    void Add_Bond(AtomBase i_AtomBonded,  int BondType){ 
    	Links Link1 = {i_AtomBonded, BondType};
    	Linked.push_back(&(Link1));
     
    }
    Ca compile bien, pas de souci mais au moment de l'ex�cution : EXC_BAD_ACCESS !!!!
    J'ai beau chercher, je sais que ca vient de Linked.push_back(&(Link1)); qu'il aime pas mais j'arrive pas � savoir pourquoi ....
    Un petit coup de main s'il-vous-plait !! Ca fait 1h30 que je cherche � je commence � d�sesperer. Merci d'avance !

  2. #2
    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, et bienvenue sur le forum.

    Le fait est que tu te laisse avoir � une erreur classique lorsque l'on manipule des pointeurs: tu prend l'adresse d'une variable locale � ta fonction et qui est donc d�truite... lorsque l'on atteint l'accolade fermante:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Add_Bond(AtomBase i_AtomBonded,  int BondType){ 
         // ceci est une variable locale... elle n'existe que pour la
         //  durée de l'exécution de Add_bond
        Links Link1 = {i_AtomBonded, BondType}; // ca compile, ca?
     
    	Linked.push_back(&(Link1)); // tu prend l'adresse mémoire de link1, 
                                        // mais...
     
    } //link1 est détruit ici, son adresse devient donc invalide
    Tu dois donc faire en sorte que la variable continue d'exister une fois que l'on a quitt� la fonction, et, pour ce faire, il n'y a pas trente six solutions: il faut passer par l'allocation dynamique de la m�moire
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    void Add_Bond(AtomBase i_AtomBonded,  int BondType){ 
        Links *Link1 = new Links(/*...*/);
     
    	Linked.push_back(Link1); // on ajoute le pointeur
     
    } // on a pris la responsabilité de la gestion de la durée de vie de Link1...
      // la variable continue donc d'exister...
    Par contre, cela implique qu'il faut �tre particuli�rement vigilent pour le reste de la gestion de Linked:
    1. Si la m�moire allou�e � un pointeur contenu dans Linked est lib�r�e, la classe qui utilise Linked doit en �tre tenue inform�e et... supprimer le pointeur invalid�
    2. Lorsque l'on supprime un �l�ment de Linked, il faut veiller �... lib�rer la m�moire au plus tard avant de perdre toute r�f�rence � l'emplacement m�moire utilis�, sous peine d'observer une fuite m�moire
    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 averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par d�faut
    Merci Koala pour la rapidit� de la r�ponse.
    J'ai cru voir la r�ponse d'un mod�rateur qui a enlev� son com' y'a 30 secondes disant que toutes utilisations ult�rieures seraient fauss�es. En effet, c'est bien le cas.

    J'ai essay� l'utilisation de Links *Link1 = new Links(i_AtomBonded,BondType);
    mais ca ne marche pas. Au risque de paraitre faignant et abusif sur ce coup l�, un dernier coup de main. D�sol� mais je sature completement de ce probleme.

    Pour le reste je vais m'arranger dans le destructeur pour bien v�rifier que tout est bien d�sallou�. Merci encore.

  4. #4
    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
    Citation Envoy� par gilims Voir le message
    Merci Koala pour la rapidit� de la r�ponse.
    J'ai cru voir la r�ponse d'un mod�rateur qui a enlev� son com' y'a 30 secondes disant que toutes utilisations ult�rieures seraient fauss�es. En effet, c'est bien le cas.
    Effectivement, Bruno a post� une r�ponse et l'a retir�e tout de suite apr�s avoir remarqu� (bien que n'y �tant pas oblig�) que j'avais r�pondu moins succinctement mais dans le m�me sens que lui...
    J'ai essay� l'utilisation de Links *Link1 = new Links(i_AtomBonded,BondType);
    mais ca ne marche pas. Au risque de paraitre faignant et abusif sur ce coup l�, un dernier coup de main. D�sol� mais je sature completement de ce probleme.
    Et pour cause, il n'existe aucun constructeur de Links prenant deux arguments

    J'avais perdu de vue qu'il s'agissait d'une structure pour laquelle il n'y a aucun constructeur d�fini par toi, ce qui fait que les Big Four sont de mise.

    Essaye peut �tre avec:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    Links *Link1 = new Links;
    Link1->Atome = i_AtomBonded;
    Link1->Type = BondType;
    (au passage, on peut signaler que l'utilisation d'une r�f�rence pour le membre Atome de ta structure risque tr�s fortement de poser des probl�mes par la suite )
    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

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par d�faut
    Ok j'ai r�ussi � faire le constructeur de la structure
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    Links::Links(AtomBase Atome1,int Type1) { Atome=&Atome1; Type= Type1;}
    J'ai un peu modifier la structure
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    struct Links
    {
    	Links(AtomBase Atome1,int Type1);
    public:
    	AtomBase *Atome;
    	int Type;
     
    	};

    Et le code d'ajout :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    void AtomBase::Add_Bond(AtomBase i_AtomBonded,  int BondType){ 
    	Links *Link1 = new Links(i_AtomBonded,BondType);
     
    	//(*Link1).Atome = i_AtomBonded;
    	Linked.push_back(Link1);
     
    }
    Cependant, on en reviens � ce que Bruno et toi disiez, l'acc�s aux donn�es pose un probl�me :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    cout << Linked[0].Type << endl;
    Ca continue � me renvoyer un EXC_BAS_ACCESS.

    Et l� on parle m�me pas de l'�l�ment Atome, mais juste d'un integer.
    Je suis d�sesp�r� .... ^^

  6. #6
    Membre �m�rite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    D�tails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par d�faut
    Pourquoi tu utilises des pointeurs si tu ne sais pas t'en servir?

    Est-ce qu'il y en a besoin?

    Est-ce que tu as vraiment besoin d'une r�f�rence/pointeur sur AtomBase? Dans ce cas l�, pourquoi tu en passes un param�tre par copie lors de la construction?

    voil� mon conseil: commence simple et r�fl�chis � ce que tu veux faire.

    La solution simple:
    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
     
    struct Link
    {
        Link( const AtomBase & atome, 
                int type )
        : atome_( atome),
          type_( type )
        {}
     
        AtomBase atome_;
        int type_;
    };
     
    std::vector<Link> links;
     
    void add_bond( const AtomBase & atomBonded,  int bondType)
    { 
    	links.push_back( Link( atomBonded, bondType )  ); 
    }

    Bon par contre, le C++, ce n'est pas du C, ce n'est pas du Java, va falloir revoir quelques bases (la FAQ C++ developpez.com?)

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par d�faut
    Au moins c'est de la r�ponse !!!
    Pourquoi tu utilises des pointeurs si tu ne sais pas t'en servir?
    Pas trop le choix pour bien g�rer le programme. Je sais que je d�teste ca et que je comprends pas forc�ment mais c'est en forgeant qu'on devient forgeron.

    Est-ce qu'il y en a besoin?
    Est-ce que tu as vraiment besoin d'une r�f�rence/pointeur sur AtomBase?
    D�finitivement oui. 2 atomes sont reli�s par 1 Bond (liaison). Si je n'utilise pas des r�f�rences/pointeurs, je perds sur le controle sur toute possibilit� de modification.

    Dans ce cas l�, pourquoi tu en passes un param�tre par copie lors de la construction?
    C'est bien ce que je me disais, mais j'avoue je n'�tais pas sur.

    Bon par contre, le C++, ce n'est pas du C, ce n'est pas du Java,
    Juste pour �tre certain, on a le droit d'utiliser des structures de donn�es en C++, ca je pense. Mais que vaut-il mieux faire pour ce cas l� ??

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par d�faut
    Eh ben, j'aurais jamais cru m'en sortir de ce probl�me. Tout marche, sans aucune fuite m�moire ... ou presque. J'ai juste un d�tail qui va para�tre nul par rapport � tout ce qu'on a dit pr�c�demment mais bon. J'ai r�ussi � bien faire les liens entre atomes->liaisons et liaisons->atomes. J'arrive � lire les donn�es des atomes dans la classe liaison, mais pas l'inverse.

    Tout ce que trouve mon compilateur � dire, avec cet AtomBase.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
     
    class BondBase;
     
    class AtomBase
    {
    private:
    	unsigned int	 Num;
    	list <BondBase*> Links;
    public:
    	void __ToString();
    	~AtomBase();
     
    	AtomBase(int _Num);
     
    	unsigned int Get_Num();
     
    	void Set_Num(unsigned int _Num);
     
    	list<BondBase*>::iterator Link;
    	void Add_link(BondBase* _Link);
    	void Unlink(BondBase* _Link);
    	bool Has_Link();
     
     
    };
    c'est : Forward declaration of 'struct BondBase' ...
    Apr�s ca, je mets en r�solu.

  9. #9
    Mod�rateur
    Avatar de bruno_pages
    Homme Profil pro
    ing�nieur informaticien � la retraite
    Inscrit en
    Juin 2005
    Messages
    3 551
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 65
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : ing�nieur informaticien � la retraite
    Secteur : High Tech - Produits et services t�l�com et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 551
    Par d�faut
    Dans AtomBase.h on d�clare que BondBase est une classe (class BondBase), c'est une forward declaration.

    Donc un fichier qui inclut AtomBase.h sait juste que BondBase est une classe, rien de plus, mais si le code utilise 'vraiment' la classe alors il y a un probl�me car sa d�finition est inconnue et le compilateur r�le

    il suffit donc de savoir quel est le .cpp qui ne se compile pas et d'ajouter dans celui-ci un #include "BondBase"

    aucune fuite m�moire ... ou presque
    il faut apprendre � corriger cela, c'est valgrind qui les signale ?
    Bruno Pag�s, auteur de Bouml (freeware), mes tutoriels sur DVP (vieux, non � jour )

    N'oubliez pas de consulter les FAQ UML et les cours et tutoriels UML

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2009
    Messages
    53
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2009
    Messages : 53
    Par d�faut
    il faut apprendre � corriger cela, c'est valgrind qui les signale ?
    C'�tait juste pour le plaisir.
    En r�alit� j'en ai h�l�s absolument aucune id�e. valgrind ne marche pas avec mon syst�me (Mac 10.6). J'utilise XCode pour trouver les fuites de m�moires, mais il avait pas r�ussi � me dire ce que j'attendais sur le probl�me pr�c�dent (probl�me que vous avez r�solu avec Valgrind). Je vais continuer � chercher un programme �quivalent qui fonctionne avec des programmes 64 bits.

    Pour le petit probleme de BondBase.h c'est r�gl�, il �tait manquant dans AtomBase.cpp.

    En tout cas, un grand merci � vous pour votre aide et vos petits conseils gliss�s par ci et l�.

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Utilisation de vector
    Par mooglwy dans le forum SL & STL
    R�ponses: 6
    Dernier message: 21/02/2007, 17h10
  2. R�ponses: 19
    Dernier message: 14/11/2006, 16h45
  3. [XML] utilisations de fichiers � m�me structures
    Par mariemor64 dans le forum XML/XSL et SOAP
    R�ponses: 9
    Dernier message: 05/10/2006, 11h29
  4. utilisation classe vector et supression de doublons
    Par vandevere dans le forum SL & STL
    R�ponses: 1
    Dernier message: 30/06/2005, 11h17
  5. Probl�me d'utilisation de vector
    Par loupdeau dans le forum SL & STL
    R�ponses: 12
    Dernier message: 28/02/2005, 12h05

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