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 :

std::sort() sur std::vector()


Sujet :

SL & STL C++

  1. #1
    tut
    tut est déconnecté
    Membre averti
    Avatar de tut
    Inscrit en
    Juillet 2002
    Messages
    373
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 373
    Points : 394
    Points
    394
    Par défaut std::sort() sur std::vector()
    Bonjour,
    soit un std::vector:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef std::vector<Station*> ListStation;
    ListStation m_ListStation;
    La classe Station est une classe que j'ai défini.
    Je veux trier le vector, pour cela je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::sort( m_ListStation.begin(), m_ListStation.end(), stationPtrCompare );
    la fonction stationPtrCompare() est déclarée comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool stationPtrCompare( Station* p1, Station* p2 )
    elle est de portée globale.

    Bon, ça compile, no problemo.

    MAIS, quand j'exécute ça plante : "access violation".
    En utilisant le debugger (Visual C++ 6.0), je vois que ma fonction stationPtrCompare() est appelée avec p1==0xcdcdcdcd.
    Hum, ça sent le pointeur pourri.
    Donc, juste avant d'appeler std::sort, je dumpe le contenu de mon vector, comme ceci :
    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
     
    /*! sort the station collection */
    void StationCollection::sortStationCollection()
    {
    	// TEST JULIEN
    	char Buff[255];
    	for (int i=0; i<m_ListStation.size(); i++)
    	{
    		sprintf( Buff, "m_ListStation[%d]=%X\n",i,m_ListStation[i]);
    		TRACE(Buff);
    	}
     
     
    	std::sort( m_ListStation.begin(), m_ListStation.end(), stationPtrCompare );
    }
    je sais, sprintf()/char[] c'est du C, mais, c'est du code de débuggage.
    Bref, le pointeur 0xcdcdcdcd ne se trouve pas dans mon vector juste avant l'appel à std::sort.
    Je ne comprends pas pourquoi ma fonction stationPtrCompare() est appelée avec cette valeur bizarre.
    Ca m'étonnerait très fortement que la STL fournie avec Visual C++ 6.0 soit buggée sur un truc aussi utilisé que cela.
    Des idées ? :

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Il y a quoi à l'intérieur de stationPtrCompare ? (juste pour pinailler, pourquoi ne pas en faire un foncteur ?).

    Sinon comme d'hab, essaie de faire un code complet minimal qui reproduise le problème , ça permet souvent de tomber sur l'origine du problème.

  3. #3
    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 : 49
    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 Re: std::sort() sur std::vector()
    Citation Envoyé par tut
    Ca m'étonnerait très fortement que la STL fournie avec Visual C++ 6.0 soit buggée sur un truc aussi utilisé que cela.
    Il y a pourtant des bugs sur des trucs si utilisés (mais je ne sais pas si ça s'applique à ton cas). Chez moi, trier un grand vecteur revenait à le tronquer. Après avoir appliqué les conseils trouvés là : http://www.dinkumware.com/vc_fixes.html ca c'est mieux passé.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    tut
    tut est déconnecté
    Membre averti
    Avatar de tut
    Inscrit en
    Juillet 2002
    Messages
    373
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 373
    Points : 394
    Points
    394
    Par défaut
    @Loulou24 : il y a ça :
    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
    /*! this function is used to compare two station pointers */
    bool stationPtrCompareFreq( Station* p1, Station* p2 )
    {
     
    	bool Res = false;
     
    	if ( !(p1&&p2) )
    		return Res; // error
     
    	switch ( Station::m_SortField )
    	{
    		case Station::Freq:
    			Res =  p1->getDFreq() < p2->getDFreq();
    			break;
    		case Station::Pi:
    			Res = p1->m_Pi < p2->m_Pi;
    			break;
    		case Station::PsName:
    			Res = p1->m_PsName < p2->m_PsName;
    			break;
    		case Station::Pty:
    			Res = p1->m_Pty < p2->m_Pty;
    			break;
    		case Station::Fs:
    			Res = p1->m_POCWStationQuality.m_FieldStrength < p2->m_POCWStationQuality.m_FieldStrength;
    			break;
    	}
     
    	if ( Station::m_SortType == Station::descen )
    		Res = !Res;
     
    	return Res;
    }
    C'est curieux parce que le problème n'apparaît pas lorsque l'on fait un tri sur Station::Freq, qui compare des double, alors qu'il apparaît sur les autres, qui eux comparent des std::string. Je crois qu'il y a baleine sous caillou là, je vais chercher dans cette direction.
    Qu'est-ce que tu veux dire par foncteur ? déclarer un type foncteur pour l'utiliser avec std::sort() ?
    De toute façon, je crois que je vais refaire cette fonction : je peux mettre le switch case ailleurs de telle sorte qu'il soit appelé avant std::sort(), comme ça je gagne autant de switch/case inutiles... Il me faudra créer une fonction de comparaison spécifique pour chaque case.

    @JolyLoic : je ne savais pas que cela éxistait. Est-ce que tu as essayé le header qu'ils proposent à l'adresse que tu spécifies ? mon vecteur n'est pas énorme : 206 éléments, qui sont des pointeurs.

  5. #5
    Membre éprouvé Avatar de Caine
    Inscrit en
    Mai 2004
    Messages
    1 028
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Mai 2004
    Messages : 1 028
    Points : 1 122
    Points
    1 122
    Par défaut
    Bonjour,

    C'est ici que les bactéries attaquent, surtout si une des deux chaînes est vide (null). Pour comparé des chaînes utilises plutôt strcmp.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         case Station::PsName:
             Res = p1->m_PsName < p2->m_PsName;
             break;

  6. #6
    tut
    tut est déconnecté
    Membre averti
    Avatar de tut
    Inscrit en
    Juillet 2002
    Messages
    373
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 373
    Points : 394
    Points
    394
    Par défaut
    il y a des chaînes vides, c'est sûr.
    Mais pourquoi donc le fait de comparer une chaine vide avec une non vide peut engendrer des erreurs ?
    J'ai chercher dans les différentes doc à ma disposition sur std::string, je ne vois aucune mise en garde là-dessus...
    Bon, par contre, je dois reconnaitre que le fait d'utiliser strcmp() ne fait plus planter le bazar...
    Merci !
    au moins, j'aurai appris des trucs.

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Attention à ce que tu renvoies dans ta fonction de tri : elle doit indiquer si le premier est strictement inférieur au second. Hors quand tu tries en ordre décroissant, tu fais la négation de l'inférieur strict, ce qui te donne un supérieur ou égal.

    Ce genre d'erreur dans les set ou map peut créer beaucoup de problèmes, par contre avec sort je ne sais pas dans quelle mesure c'est gênant et si ça peut provoquer ce genre de bug.

  8. #8
    tut
    tut est déconnecté
    Membre averti
    Avatar de tut
    Inscrit en
    Juillet 2002
    Messages
    373
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 373
    Points : 394
    Points
    394
    Par défaut
    bien vu !
    je corrige ça... 8)

  9. #9
    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 : 49
    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
    Citation Envoyé par tut
    je ne savais pas que cela éxistait. Est-ce que tu as essayé le header qu'ils proposent à l'adresse que tu spécifies ?
    On l'utilise au boulot quotidiennement depuis quelques années. Après tout, c'est quand même le site de ceux qui on fait la bibliothèque standard pour Visual C++, on peut leur faire confiance.
    Citation Envoyé par tut
    mon vecteur n'est pas énorme : 206 éléments, qui sont des pointeurs.
    Ce n'est effectivement pas gros.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  10. #10
    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 : 49
    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
    Citation Envoyé par Caine
    C'est ici que les bactéries attaquent, surtout si une des deux chaînes est vide (null). Pour comparé des chaînes utilises plutôt strcmp.
    L'opérateur < est tout à fait correct pour comparer des std::string. Même vides.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Inscrit Avatar de bilb0t
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    378
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 378
    Points : 283
    Points
    283
    Par défaut
    Bonjour,

    je me permet de déterer ce vieux post car je me pose une question. Est-ce que c'est "threadSafe" d'utiliser une variable static pour spécifier le type de tri (ou j'ai peut être rien compris).

    Merci.

    Citation Envoyé par tut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /*! this function is used to compare two station pointers */
    bool stationPtrCompareFreq( Station* p1, Station* p2 )
    {
     
    	switch ( Station::m_SortField )
    	{...}
     
    }

  12. #12
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    A priori, non... A moins de bloquer le mutex, d'une en entrant dans la boucle de tri et deux, avant de modifier le type de tri.
    Ou de respecter une discipline stricte (mais scabreuse vis-à-vis de la maintenance).

    Mais là il est pas question de thread, ou c'est moi qu'est rien compris ?

    Citation Envoyé par tut
    Hum, ça sent le pointeur pourri.
    Gaïa n'est pas une marchandise.

  13. #13
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    static et thread safe se marrient difficilement.

  14. #14
    Inscrit Avatar de bilb0t
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    378
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 378
    Points : 283
    Points
    283
    Par défaut
    ok, j'ai déclarer un object et redéfini l'opérateur() pour être thread safe.

    Merci.

  15. #15
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Désol pour les yeux ronds...
    Pas bien comprite en fait, tu l'utilises comment, l'operator() ?

    Simple curiosité...
    Gaïa n'est pas une marchandise.

  16. #16
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Citation Envoyé par SKZ81
    Désol pour les yeux ronds...
    Pas bien comprite en fait, tu l'utilises comment, l'operator() ?

    Simple curiosité...
    Voir http://c.developpez.com/faq/cpp/?page=STL#STL_functor et les 2 exemples qui suivent.

  17. #17
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    OK et merci...
    Je connaissais la surcharge d'ops, et () également, mais cette utilisation m'était inconnue...
    "On nous cache tout, on nous dis rien !!!" Ha !! Les profs !

    Bref... Par contre dans l'exemple, en l'occurence, je ne vois toujours pas comment ça s'utilise...
    Je veux dire, comment que Bilb0t y s'en sert ?? (J'aime bien parler bien, comme ça!!)

    Tu peux m'dire, s'teup??
    Gaïa n'est pas une marchandise.

  18. #18
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 750
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 750
    Points : 10 667
    Points
    10 667
    Billets dans le blog
    3
    Par défaut
    C'est la STL qui appelle simplement l'opérateur, comme t'appelerait une fonction sauf que là c'est un objet (d'où le nom de fonction objet->functor). Tu peux regarder dans le code STL de std::sort.

  19. #19
    Inscrit Avatar de bilb0t
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    378
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2003
    Messages : 378
    Points : 283
    Points
    283
    Par défaut
    J'aurais pas répondu mieux...

  20. #20
    Membre habitué
    Profil pro
    Enculeur de mouches
    Inscrit en
    Septembre 2003
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Creuse (Limousin)

    Informations professionnelles :
    Activité : Enculeur de mouches

    Informations forums :
    Inscription : Septembre 2003
    Messages : 133
    Points : 161
    Points
    161
    Par défaut
    Ok j'ababonne... Si vous vous obstinez à m'expliquer des trucs que j'ai compris...


    Je vois toujours pas pkoi un foncteur (qui effectue le tri) rend thead safe la modif du mode tri, qui a priori se fait pas pendant le tri (ou alors )
    Gaïa n'est pas une marchandise.

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

Discussions similaires

  1. Pointeur sur std::vector casser après un resize()
    Par jerem3000 dans le forum Langage
    Réponses: 3
    Dernier message: 20/01/2012, 00h30
  2. Manipulations de vector, std::sort et std::unique
    Par dhoorens dans le forum C++
    Réponses: 4
    Dernier message: 16/11/2007, 09h41
  3. [Tuto] Recherche de tutoriel sur std::list et std::vector
    Par pegase06 dans le forum SL & STL
    Réponses: 27
    Dernier message: 24/07/2007, 16h23
  4. Question sur std::vector
    Par FabaCoeur dans le forum SL & STL
    Réponses: 11
    Dernier message: 24/06/2007, 18h22
  5. tri sur std::vector<std::pair<int, float> >
    Par b4u dans le forum SL & STL
    Réponses: 15
    Dernier message: 01/10/2006, 09h19

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