2016-08-18 1 views
1

J'ai une commande std :: map pour stocker des pointeurs vers des objets associés à leur ID respectif. Quand je boucle sur la carte pour obtenir le contenu de celui-ci, je reçois un mauvais retour sur le premier essai, mais un bon sur les prochaines essais:std:: l'itération de la carte tourne mal lors de la première exécution

class session_list { 
private: 
    ... 
    static std::map<uint, session*> session_list; 
    ... 
public: 
    ... 
    static void add_exclusive_session(uint id, session& session); 
    ... 
    std::map<uint, session*>& get_session_list() ; 
}; 
std::map<uint, core_base_session*>& core_session_list::get_session_list() { 
    return session_list; 
} 

void session_list::add_exclusive_session(uint id, session& session) { 
    guard g(mutex); 
    if (session.disconnect_reason != core_sd_connected) 
     return; 
    session * previous_session = get_session(id, g); 
    session_list.emplace(id, &session); 
    if ((previous_session != nullptr) 
     &&(previous_session != &session)) { 
    previous_session->disconnect(core_sd_peer_duplicated); 
    } 
} 
std::map<uint, session*> session_list = 
    session.parent.session_list->get_session_list(); 
for (auto& it: session_list) { 
    printf("\n\tSESSION N° %d \t %p" , it.first, it.second); 
} 

Il dumps ceci:

2016-08-18 14:57:23.103881 [info] DBG_ 

     SESSION N° 1402969504 0x7efc400008c0 <=== APPEARS TWICE 
     SESSION N° 574745422  0x1a469f0 
     SESSION N° 1402969504 0x7efc400008c0 <=== APPEARS TWICE 
     SESSION N° 1502939797 0x7efc48000ca0 
     SESSION N° 1510611043 0x7efc3c000ca0 
2016-08-18 14:57:38.245280 [info] DBG_ 

     SESSION N° 2011917896 0x7efc44000ca0 <=== APPEARS NOT ON FIRST TRY 
     SESSION N° 574745422  0x1a469f0 
     SESSION N° 1402969504 0x7efc400008c0 
     SESSION N° 1502939797 0x7efc48000ca0 
     SESSION N° 1510611043 0x7efc3c000ca0 

Une idée?

+1

Voulez-vous publier le code 'get_session_list'? –

+0

Ma première supposition serait que la première sortie de 'DBG_' est réellement sortie de * deux * exécutions de l'extrait en question, affiché dos-à-dos. – NPE

+1

Etes-vous sûr que la liste des sessions n'a pas changé pendant les quinze secondes qui séparent les enregistrements du journal? Vous êtes susceptible de devoir produire un MCVE ([MCVE]), et vous aurez probablement du mal à produire un MCVE qui reproduit le problème, IMO. Mais sans que nous en sachions beaucoup plus sur ce qui se passe, nous ne serons pas en mesure d'aider beaucoup, je pense. –

Répondre

1

Donc, ce que nous semblons voir ici, c'est qu'un objet std::map contient deux clés identiques. Nous allons énumérer les possibilités qui pourraient expliquer ce comportement (du moins probablement le plus probable):

  • est fondamentalement cassé de votre compilateur std::map et permet à plusieurs clés identiques;
  • vous avez un comportement indéfini quelque part dans votre code qui corrompt session_list;
  • la première séquence de SESSION N° lignes est produite par le code en question s'exécutant plus d'une fois, par ex.

    # run 1 
    SESSION N° 1402969504 0x7efc400008c0 <=== APPEARS TWICE 
    # run 2 
    SESSION N° 574745422  0x1a469f0 
    SESSION N° 1402969504 0x7efc400008c0 <=== APPEARS TWICE 
    SESSION N° 1502939797 0x7efc48000ca0 
    SESSION N° 1510611043 0x7efc3c000ca0 
    

Mon argent est sur la dernière. Il est difficile de dire quelle est la probabilité sans voir plus de votre code.

+0

Mon compilateur est standard GNU g ++ g ++ (Debian 4.9.2-10) 4.9.2 – MicroCheapFx

+0

Je ne comprends pas votre 3ème point. Il y a deux exécutions de la commande 'DBG_'. Cette commande exécute l'extrait une fois. – MicroCheapFx

+1

Cette version de 'g ++' et de sa librairie 'libstdC++', à cause de son inclusion dans Debian Stable, ne peut clairement pas avoir une' map' aussi "fondamentalement cassée" que ça ... donc ce n'est pas la faute de l'implémentation. –