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

Langage C++ Discussion :

Pointeur NULL dans conteneur c++


Sujet :

Langage C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut Pointeur NULL dans conteneur c++
    Bonjour,

    Je suis actuellement sur un projet et un probleme me taraude.
    Mon programme possede une map<std::string, Objet*>.

    L'objet (Enfin pointeur sur objet) en question je l'initialise et le test, il marche sans soucis.
    Malheureusement lorsque je le rentre dans ma map, le pointeur passe a NULL.

    Etant debutant en C++ et ne connaissant que tres peu le debugger de visual c++ (IDE sur lequel je developpe) je me tourne vers vous car de toute evidence il y'a un soucis ^^.

    Les sources ne sopnt pas poste car il y'a pas loin de 400 ligne pour ma classe et je ne sais pas quoi vous donner.
    Donc n'hesitez pas je reste a disposition

    Merci par avance

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

    Ce que tu pourrais donner, c'est une idée de la hiérarchie de classe basée sur Objet (car, je présumes que si tu veut placer un pointeur dans une map, c'est pour l'utiliser polymorphiquement ), la définition de ta classe objet (et plus particulièrement les fonctions virtuelles), et le code de la fonction dans laquelle tu essaye de placer cet objet dans la map...

    De manière générale, l'idéal est de donner un code minimum compilable qui reproduise le problème, mais il est vrai que, lorsque l'on travaille avec une orientation objet et une otpique polymorphe, cela signifie bien souvent fournir le code de la classe de base, celui d'au moins une classe dérivée et celui de la fonction qui pose problème
    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
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Ci-joint le fameuse Objet*

    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
     
    #ifndef _USER_HH_
    #define _USER_HH_
     
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <map>
    #include <utility>
     
    #include <boost/bind.hpp>
    #include <boost/smart_ptr.hpp>
    #include <boost/asio.hpp>
    #include <boost/thread.hpp>
     
    typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
     
    class	user
    {
    	socket_ptr	_sock;
    	std::string	_log;
    	std::string	_pwd;
    	bool		_state;
     
    public:
    	user();
    	user(bool state, socket_ptr sock);
    	user(std::string login, std::string passwd, bool state, socket_ptr sock);
    	~user();
     
    	socket_ptr		getSock() const;
    	void			setSock(socket_ptr);
    	std::string		getLog() const;
    	void			setLog(std::string&);
    	std::string		getPasswd() const;
    	void			setPasswd(std::string&);
    	bool			getState() const;
    	void			setState(bool const);
    };
    #endif //!_USER_HH_
    Et ci joint le fameux bout de code qui il me semble pourrait convenir :
    Nous sommes dans une methode
    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
     
    std::map<std::string, user*>			users;
     
    void   function2(user *u)
    {
       users.insert(std::pair<std::string, user*> (u->getLog(), u));
       /* Truc bidon d'exemple mais il ne le match meme pas dans le tableau */
       std::cout << "Authentification de " << users[u->getLog()]->getLog() << std::endl;
     
       /* Et si toute fois il le matchait, le pointeur serait vide */
    }
     
     
    void    function1()
    {
       if (1)
       {
          user *u = new user(false, sock);
          u->setLog() = "Toto";
          function2(u);
       }
    }
    Le code n'est peut etre pas aussi complet que ce que tu m'as demande neamoins il represente le bout de code qui pose probleme

    Cordialement,

  4. #4
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Je ne pense pas que ça resoudra ton problème, mais tu devrais utiliser std::make_pair plutot que cette syntaxe.

    Au delà de ça, tu peux peut être ajouter une assertion ( != null) au début de ta fonction voir?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Je ne pense pas que ça resoudra ton problème, mais tu devrais utiliser std::make_pair plutot que cette syntaxe.
    Je viens d'essayer et e effet le resultat est le meme

    Au delà de ça, tu peux peut être ajouter une assertion ( != null) au début de ta fonction voir?
    Cela ne fera que contourner le probleme en cas de non respect de la condition (Ce qui se passe en ce moment).

  6. #6
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Ce que je voulais dire, c'est qu'avec l'assertion, au moins tu sais que le code de ta fonction est correct et que le problème viens de l'extérieur, autrement dit du new user(...).

    Sauf bien sur si l'assertion de faillis pas.

    Au passage, pourquoi

    Compile?

    setLog requiert un paramettre et retourne void, ce code ne devrait pas compiler...

  7. #7
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Ok je commence a comprendre, si tu as voulu faire



    Alors tu pensais peut être assigner la valeur au string contenu dans (*u), mais en réalité tu l'assigne à une copie. Ca rends l'insertion dans la map fausse puisque u->getLog() a toujours la valeur par défaut "".

    Pour que ça marche, getLog() doit retourner une référence, pas une copie.
    Je serais toi, je mettrais plutot getLog() const qui retournerait une référence constante, obligeant l'utilisateur a utiliser setLog() (et ça crasherait si on essayait de faire autrement).

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Non du tout c'est moi dans la precipitation qui me suit tromper
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    u->setLog("Toto");
     
    std::cout << u->getLog() << std::endl;

  9. #9
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Dans ce cas, "la vérité est ailleurs"

    On peut voir le code de setlog et getlog?

    A mon avis getlog ne retourne pas ce a quoi on s'attends...certainement parceque setlog ne fait pas exactement ce qu'on pense...

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Honnetement j'en doute le getLog me retourne ce que j'attend de lui, la ou ca peche c'est la map d'objet*.
    Lorsque je cherche a l'utiliser, la key est bonne mais l'objet se situe en 0x000000.
    Soit un pointeur NULL.

    getLog et setLog son des geteurs et seteurs tout ce qu'il y'a de plus banale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    std::string		user::getLog() const
    {
    	return (this->_log);
    }
     
    void			user::setLog(std::string& log)
    {
    	this->_log = log;
    }

  11. #11
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    C'est le comportement de la map quand la clée ne corresponds à rien dans la map (elle insert un nouvel enrgistrement avec une valeur par défaut pour la valeur liée a la clée, soit NULL pour un pointeur).

    Autrement dit soit tu insert bien null (mais tu dis que c'est pas nul a l'insertion?) soit il y a quelque chose d'incorect dans getLog ou setLog, donc sans montrer le code je vois pas comment t'aider.

    Ce ne sont pas des accesseurs triviaux? (au passage, tu devrais passer une référence constante dans setLog, mais ça devrait pas changer grand chose au problème.)

    edit> Ok alors le problème est encore autre part.

  12. #12
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Essaie de mettre un breakpoint sur la ligne d'insertion, et regarde dans les variables du debugger voir le contenu de ta map après l'insertion.

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Reponse du debugger :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    +users[1](("Nox",0x00000000 {_sock={...} _log={...} _pwd={...} ...}))
    std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,user *,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,user *> > >
    On dirait qu'il ne prend pas en compte le pointeur que je lui met a l'insertion ... Ca m'inirve ^^ Pourtant je le teste avec des getLog() avant et il me renvoi la bonne valeur !

  14. #14
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Juste pour voir le comportement, essaie de faire:

    users[ u->getLog() ] = u;

    a la place de l'insertion?

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Tu peux aussi :
    1/ Tester la valeur en retour de ton insertion: (std::pair<iterator,bool>, teste si l'itérateur est valide et si bool est vrai (nouvel élément) ou faux (élément déjà existant)
    2/ Essaies std::map::find juste après ton insertion. Vérifie si l'itérateur et valide et alors quelle est l'@ de user.

    Accessoirement, je ne vois pas l'intérêt de stocker les user par pointeur vu que les membres de user utilisent déjà le RAII pour les données allouées.

  16. #16
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Je crois que Klaim a trouve la solution neamoins je ne comprends pas bien pourquoi ):

    En revanche je n'ai pas compris l'histoire des RAII, puis je avoir une explication ?

    Merci par avance

    ps : Je mange, finis mes test et passe le topic a Resolu un fois les tests finis.

  17. #17
    Membre expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Points : 3 344
    Points
    3 344
    Par défaut
    Ce n'est pas normal...
    le code que je t'ai proposé crée une pair avec un pointeur null comme valeur et la clée donnée comme clée, puis assigne au pointeur la valeur après le =.

    Si ça ça marche, alors l'insertion doit marcher aussi.

    Ou alors il y a un problème plus grave dans ton programe : vérifie l'état de ta map avant l'insertion voir si il n'y a pas des trucs louches dedans.

    Il se peut qu'un autre bout de programme touche a la map... ou à la mémoire qu'elle manipule. Auquel cas, bonne chance

  18. #18
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Bien entendu j'initialise mon user avant et je le rentre de l maniere que tu m'as dit dans ton dernier post et ca a regle le truc... magiquement

  19. #19
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Quel compilateur as-tu ? Comme Klaim, je ne vois pas pourquoi []= corrigerait le bug de insert
    Concernant le stockage valeur/pointeur :
    1/ Ta classe ne contient aucune fonction virtuelle ;
    2/ la socket est stockée sous forme de pointeur intelligent ;
    3/ les autres membres sont 2 string et un booléen.
    Tout ça se copie très bien et je ne pense pas qu'il y ait un coût rédhibitoire.
    Donc, pourquoi ne pas avoir une map par valeur : std::map<std::string,user> ? Si tu veux vraiment mettre des pointeurs, pourquoi ne pas avoir mis des pointeurs intelligent ?
    De la même façon, si c'est pour mettre des accesseurs aux membres de ta classe, et bien, rends carrément public ces membres. Ca ne sert à rien de les mettre en privé si c'est pour ajouter des getter/setter.

  20. #20
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 15
    Points : 5
    Points
    5
    Par défaut
    Yop

    Quel compilateur as-tu ? Comme Klaim, je ne vois pas pourquoi []= corrigerait le bug de insert
    J'uilise celui par default de visual c++ je ne pourrais pas te donner le nom comme ca, que cette methode marche m'egare neamoins je pense simplement que mon u->getLog() doit etre different d'une string entre double quotes.
    (A cause des constante ?)

    1/ Ta classe ne contient aucune fonction virtuelle ;
    2/ la socket est stockée sous forme de pointeur intelligent ;
    3/ les autres membres sont 2 string et un booléen.
    Tout ça se copie très bien et je ne pense pas qu'il y ait un coût rédhibitoire.
    Donc, pourquoi ne pas avoir une map par valeur : std::map<std::string,user> ?
    Il y'a une grosse difference en memoire entre un pointeur et une reference ?
    On m'a explique qu'une reference etait un pointeur qui ne pouvait etre NULL.

    Si tu veux vraiment mettre des pointeurs, pourquoi ne pas avoir mis des pointeurs intelligent ?
    Je viens de "decouvrire" la notion de pointeur intelligent, je vais pousser un peu le delire

    De la même façon, si c'est pour mettre des accesseurs aux membres de ta classe, et bien, rends carrément public ces membres. Ca ne sert à rien de les mettre en privé si c'est pour ajouter des getter/setter.
    Question de convention scolaire actuellement, mais surtout question de logique au cas ou un tiers reprendrait mon code.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Déréférencement d'un pointeur null (dans une classe)
    Par polymorphisme dans le forum Langage
    Réponses: 5
    Dernier message: 13/09/2012, 15h44
  2. Pointeur null dans le Thread AWT-EventQueue-0
    Par le.jitou dans le forum Interfaces Graphiques en Java
    Réponses: 0
    Dernier message: 09/04/2012, 19h28
  3. Réponses: 0
    Dernier message: 07/10/2008, 10h10
  4. passage pointeur NULL dans une fonction
    Par reptils dans le forum C
    Réponses: 4
    Dernier message: 11/05/2006, 23h12
  5. [Oracle] Recherche nulle dans une base et affichage
    Par GLDavid dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 27/04/2006, 01h01

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