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 :

"Bad ptr" : impossible d'accéder à une donnée membre


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 49
    Par défaut "Bad ptr" : impossible d'accéder à une donnée membre
    Bonjour,
    J'ai les classes suivantes :

    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
     
    struct Data
    {
     string name ;
    };
     
    class Loader
    {
    public:
    Data obj[100] ;
    }
     
    void main()
    {
    Loader * loader = new Loader();
    loader->obj[0].name ; //Et bien cette ligne plante et me donne un "bad ptr" !!
    }
    la variable "name" est initialisée correctement dans le constructeur de Loader,
    mais à la ligne suivante c'est une donnée invalide et ça plante, savez vous pourquoi et comment puis je faire ?

    PS : j'ai déjà essayé de remplacer le type string de "name" par char * ou vector <char> mais rien y fait...

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Il ne faudrait pas mettre obj et name en public ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 49
    Par défaut
    Oui désolé mais je viens de corriger :
    name est dans une struct (donc tout est public) et obj est en public et le problème a bien lieu dans ce cas de figure là.

  4. #4
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Aux faits près que main doit retourner un int et un ; oublié, ce code est valide (pense néanmoins à libérer la mémoire avec delete, ou mieux, ne pas utiliser new).

    Quel est le vrai code qui plante ?
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  5. #5
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut
    Je vient de compiler ton code (avec Code::BLocks), je n'ai pas d'erreurs autres que :

    - "string", tu a bien fait tous les includes et toutes les définitions nécessaires ? (#include <string>, using..)
    - class Loader{...} ;
    - int main(){ ... return 0;}

    En faisant ces corrections, ça ne marche toujours pas ?

    Tu utilise quel IDE/Compilateur ?

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 49
    Par défaut
    j'utilise visual studio 2008, ce qu'il me manquait dans ce que tu as mis c'était le include <string> (mais ça compilait quand même bizarrement) mais j'ai toujours le même problème.

    Je n'ai pas mis tout le code car c'est un peu long. Et je suis d'accord pour dire que c'est bizarre...

  7. #7
    Membre éclairé Avatar de cs_ntd
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2006
    Messages
    598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

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

    Informations forums :
    Inscription : Décembre 2006
    Messages : 598
    Par défaut
    Je viens de test avec VS2008, et bin ça marche

    Essaye peut-être de créer un nouveau projet, et test le code minimal. Si ça marche, essaye d'importer tes fichiers dans ton nouveau projet...
    Si ça ne marche pas après l'importation, c'est qu'il manque des choses dans ton code minimal...

  8. #8
    Membre expérimenté Avatar de vikki
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    292
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 292
    Par défaut
    Le problème est-il vraiment un crash à l'exécution ou alors simplement que tu n'arrives pas à voir la valeur de la variable en mode Debug?

  9. #9
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Par défaut
    Bonjour,
    Si il y a juste une string dans ta structure la struct ne sert a rien.
    Ensuite ton ptr sur ton loader ce n'est pas nécessaire les références c'est plus cool ensuite ton tableau en dur est peut être le problème (pb de porter)
    Tu peut utiliser la class vector pour sa qui appartient a la lib stl et est donc portable.
    Et comme tu est dans le main avec des références tu n'auras pas de pb de porter

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Ça me rappelle: Est-ce qu'une std::string peut être NULL?
    Ou bien contient-elle toujours quelque chose, au minimum une chaîne vide?
    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.

  11. #11
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Essaie donc d'initialiser ou d'affecter un std::string à « NULL », tu vas t'amuser…
    Contrairement à un char*, un std::string doit toujours être valide.
    Donc au minimum, ça contient le caractère nul.

    Pour information, Qt fait la différence entre les chaînes « vides » et les chaînes « nulles ».
    Citation Envoyé par doc.qt.nokia.com
    bool QString::isEmpty () const

    Returns true if the string has no characters; otherwise returns false.

    Example:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    QString().isEmpty();            // returns true
    QString("").isEmpty();          // returns true
    QString("x").isEmpty();         // returns false
    QString("abc").isEmpty();       // returns false

    bool QString::isNull () const

    Returns true if this string is null; otherwise returns false.

    Example:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QString().isNull();             // returns true
    QString("").isNull();           // returns false
    QString("abc").isNull();        // returns false
    Qt makes a distinction between null strings and empty strings for historical reasons. For most applications, what matters is whether or not a string contains any data, and this can be determined using the isEmpty() function.

  12. #12
    Membre très actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2010
    Messages
    434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2010
    Messages : 434
    Par défaut
    la string en elle même ne peut pas êtrtre NULL un pointer de string peu l’être ou une référence peut ne pas être initialiser

  13. #13
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par jouana Voir le message
    la string en elle même ne peut pas êtrtre NULL un pointer de string peu l’être ou une référence peut ne pas être initialiser
    Meh ? Tu veux dire que

    oblige l'objet s à contenir quelque chose ?

    La string elle même peut contenir n'importe quoi, y compris un (ou deux; ou trois) pointeurs NULL. L'interface de string, par contre, impose que les données auxquelles on accède depuis l'extérieur soient tout le temps valide (ni .data(), ni .c_str() ne peuvent renvoyer NULL. Mais comme ces fonctions renvoient des const char*, elles peuvent tout à fait renvoyer la chaine "" si les pointeurs internes de std::string sont à NULL) et contiguës en mémoire (ce qui est le cas pour la chaîne constante vide ""). De même, on ne peut pas créer une chaîne à partir de NULL (cette valeur est censée être checkée par les constructeurs prenant un const char* en paramètre; en cas de valeur NULL, le constructeur a de grandes chances de planter (mais comme la norme ne dit pas qu'il doit générer une exception, on va dire que c'est un comportement indéfini).

    Et bon courage pour faire une référence non initialisée Selon le standard, une telle chose n'existe pas (comportement indéfini en cas de création ou d'utilisation).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    On ne peut pas faire de référence invalide ou non-initialisée sans jouer avec les pointeurs.

    Mais on peut initialiser une référence avec un pointeur non-initialisé.
    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.

  15. #15
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Meh ? Tu veux dire que

    oblige l'objet s à contenir quelque chose ?
    Oui.
    En tout cas pour g++.
    Le pointeur interne n'est jamais NULL, et donc pointe toujours sur quelque chose.
    Le constructeur par défaut le fait pointer sur des bits nuls, stockés statiquement par la classe.

  16. #16
    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
    Par défaut
    Le problème ne peut pas venir de std::string quel que soit l'implémentation parceque le test présent est trop simple et le bug aurait été corrigé il y a des lustres.

    Par contre, clairement il manque le reste du contexte. Donc soit on nous propose un exemple qui effectivement reproduit le problème (sachant que monter cet example peut permettre à celui qui pose la question de trouver la réponse en dépouillant son cas spécifique des "décorations"), soit on nous fournit tout le code qui reproduit le problème.

    Soit on prends les paris. Je paris sur un buffer overrun.

  17. #17
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    On ne peut pas faire de référence invalide ou non-initialisée sans jouer avec les pointeurs.

    Mais on peut initialiser une référence avec un pointeur non-initialisé.
    Ca veut pas dire que c'est une bonne idée

    Le standard n'admet pas les références invalides. Toutes les références sont invalides, et s'il rencontre une référence invalide, le comportement du programme devient indéfini (donc hors du contexte de la norme). Bref, ce n'est plus du C++

    Oui.
    En tout cas pour g++.
    Ce n'est qu'une implémentation parmi tant d'autres. Le standard se borne à donner l'interface de std::basic_string<> et d'expliciter certaines de ses obligations. Il n'impose pas une implémentation particulière.

    (Pour info, c'est aussi le cas dans la version la plus récente de la librairie standard fournie avec VC++, et c'est du à SMO (small string optimization) qui fait que toute chaine de caractère de moins de X bytes n'est pas allouée mais pointe en fait sur un buffer de X bytes. Cette optimisation implique aussi que sizeof(std::string) >= X).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

Discussions similaires

  1. Impossible d'accéder à une variable
    Par 3Dgirl dans le forum Débuter
    Réponses: 5
    Dernier message: 20/05/2009, 14h16
  2. [PHP][SOAP] Impossible d'accéder à une méthode
    Par dms75 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 30/04/2009, 12h17
  3. [OpenOffice][Tableur] Impossible d'accéder à une image
    Par adaneels dans le forum OpenOffice & LibreOffice
    Réponses: 4
    Dernier message: 24/04/2009, 04h08
  4. Module de classe : impossible d'accéder à une propriété
    Par Mathusalem dans le forum Général VBA
    Réponses: 2
    Dernier message: 10/11/2008, 14h11

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