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 :

std::set, find retourne n'importe quoi.


Sujet :

C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut std::set, find retourne n'importe quoi.
    Bonjour tout le monde!
    J'utilise un std::set pour contenir des pointeurs d'objets. J'ai défini un comparateur pour le type d'objet que je stocke.
    A certains endroits de mon programme, j'ai besoin de mettre à jour/ou ajouter un objet.

    Pour cela, je cherche l'objet dans ma liste avec la méthode find(mon_pointeur_d_objet) de la classe set puis je teste si le pointeur est nul ou non. S'il est nul alors j'ajoute l'objet sinon je le mets à jour.
    Seulement voilà: la première recherche se passe correctement à savoir la méthode find me retourne un pointeur NULL par contre au deuxième passage, le pointeur retourné est 0x1. Ceci me retourne une erreur de segmentation.

    J'ai vérifié avec le debuger (gdb) et find retourne un pointeur non correct (je devrait avoir un pointeur null).
    Plus troublant, quand je fais count(mon_pointeur_d_objet) j'obtiens bien 0...

    Voici à quoi ressemble mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    if (mon_pointeur_d_objet != NULL)
    {
       MonObjet* ptr = *(m_monSet.find(mon_pointeur_d_objet)); //retourne un pointeur à l'adresse 0x1
       if (ptr != NULL)
       {
         //modification
       }
       else
      {
        m_monSet.insert(mon_pointeur_d_objet);
      }
    }
    Je voulais savoir pourquoi est-ce que j'ai ce comportement? Est-ce normal? Est-ce que ça vous ai déjà arrivé?

    Merci d'avance


    EDIT:
    C'est bon j'ai trouvé. Il fallait plutôt faire un test sur le const_iterator pour savoir s'il c'est le dernier ou non.

  2. #2
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Salut !

    Pas de panique, ce comportement est bien normal

    En fait, cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonObjet* ptr = *(m_monSet.find(mon_pointeur_d_objet));
    find retourne un iterateur. Tu peux déréférencer un itérateur si celui-ci "pointe" bien vers un objet. Hors si find ne trouve rien, il renvoie std::end, qui ne peut être déréférencé ! Ca c'est pour la segfault.

    Tu dois donc faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    std::set::iterator mon_iter = m_monSet.find(ptr);
    if(mon_iter != monSet.end())
    {
      Objet* mon_ptr = *mon_iter; // Pas vraiment utile mais c'est pour l'exemple.
      //...
    }
    else
    //....

  3. #3
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Merci Trademark. Je viens de trouver la réponse.

  4. #4
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    J'ai envoyé mon message un peu vite, je voulais compléter par ceci :

    Ton code peut également être simplifié et n'utiliser que le insert au lieu du find suivi du insert.

    La méthode insert renvoie une pair qui contient un booléen pour dire si l'objet a été inséré et un itérateur "pointant" sur l'objet (inséré ou pas).

    Du coup tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    std::pair<std::set<Objet_ptr>::iterator,bool> res = monSet.insert(monPtr);
    if(!res.second) // L'objet existait déjà
    {
      monObjet* ptr = *(res.first); // On récupère le pointeur.
      // Modification...
    }
    // Pas de else vu qu'on a déjà inséré !

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Oui mais dans mon cas je ne peux pas faire ceci car j'ajoute l'objet seulement sous certaines conditions. (Je ne l'avais pas préciser)

    Merci quand même pour tes conseils!

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par darkman19320 Voir le message
    Oui mais dans mon cas je ne peux pas faire ceci car j'ajoute l'objet seulement sous certaines conditions. (Je ne l'avais pas préciser)

    Merci quand même pour tes conseils!
    Salut,

    Pourquoi, dés lors, ne pas commencer par vérifier l'ensemble des conditions d'insertions (existence du pointeur dans ton set mise à part), et si toutes les conditions sont remplies, tenter l'insertion

    Ne serait-ce pas plus logique

    Cela aurait, de plus, l'avantage de te permettre de déléguer beaucoup de responsabilités:

    Si, dans tout le processus qui conduit à l'insertion d'un nouvel élément, il y a une condition qui, n'étant pas remplie, empêche que cet élément ne soit inséré, il y a de fortes chances que d'autres actions devront, elles aussi, ne pas avoir lieu

    Tu te retrouverais donc dans un ensemble de situations donnant chaque fois un "go / nogo" vers l'étape suivante
    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

  7. #7
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Merci koala pour ta réponse.

    Je vais me pencher sur ton idée. Je fais de la reprise de code et je ne maitrise pas encore totalement tout l'algo qu'il y a derrière.

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

Discussions similaires

  1. Constness et std::set::find
    Par Agoudard dans le forum SL & STL
    Réponses: 6
    Dernier message: 28/03/2011, 16h40
  2. CV_CAP_PROP_FPS retourne n'importe quoi
    Par Zennoi dans le forum OpenCV
    Réponses: 1
    Dernier message: 23/08/2010, 03h49
  3. std::set et find()
    Par Harooold dans le forum SL & STL
    Réponses: 1
    Dernier message: 04/01/2009, 16h25
  4. [débutant] set linesize me fait n'importe quoi
    Par Mathusalem dans le forum Oracle
    Réponses: 6
    Dernier message: 20/04/2006, 16h22
  5. find() de std::set avec fonction de comparaison
    Par Biglo dans le forum SL & STL
    Réponses: 3
    Dernier message: 13/01/2006, 08h50

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