2010-03-27 6 views
1

Je suis tombé sur ce que je crois être un bug dans le stl algorithm advance.problème avec std :: avance sur std :: ensembles

Lorsque j'avance l'itérateur hors de la fin du conteneur, j'obtiens des résultats incohérents. Parfois, je reçois container.end(), parfois je reçois le dernier élément. Je l'ai illustré cela avec le code suivant:

#include <algorithm> 
#include <cstdio> 
#include <set> 

using namespace std; 
typedef set<int> tMap; 

int main(int argc, char** argv) 
{ 
    tMap::iterator i; 
    tMap the_map; 

    for (int i=0; i<10; i++) 
     the_map.insert(i); 

#if EXPERIMENT==1 
    i = the_map.begin(); 
#elif EXPERIMENT==2 
    i = the_map.find(4); 
#elif EXPERIMENT==3 
    i = the_map.find(5); 
#elif EXPERIMENT==4 
    i = the_map.find(6); 
#elif EXPERIMENT==5 
    i = the_map.find(9); 
#elif EXPERIMENT==6 
    i = the_map.find(2000); 
#else 
    i = the_map.end(); 
#endif 

    advance(i, 100); 

    if (i == the_map.end()) 
     printf("the end\n"); 
    else 
     printf("wuh? %d\n", *i); 

    return 0; 
} 

Ce que je reçois le comportement inattendu (selon moi) à la suite de l'expérience 3 et 5 où je reçois le dernier élément au lieu de the_map.end().

[[email protected] advance]$ uname -srvmpio 
Linux 2.6.18-1.2798.fc6 #1 SMP Mon Oct 16 14:37:32 EDT 2006 i686 athlon i386 GNU/Linux 
[[email protected] advance]$ g++ --version 
g++ (GCC) 4.1.1 20061011 (Red Hat 4.1.1-30) 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

[[email protected] advance]$ g++ -DEXPERIMENT=1 advance.cc 
[[email protected] advance]$ ./a.out 
the end 
[[email protected] advance]$ g++ -DEXPERIMENT=2 advance.cc 
[[email protected] advance]$ ./a.out 
the end 
[[email protected] advance]$ g++ -DEXPERIMENT=3 advance.cc 
[[email protected] advance]$ ./a.out 
wuh? 9 
[[email protected] advance]$ g++ -DEXPERIMENT=4 advance.cc 
[[email protected] advance]$ ./a.out 
the end 
[[email protected] advance]$ g++ -DEXPERIMENT=5 advance.cc 
[[email protected] advance]$ ./a.out 
wuh? 9 
[[email protected] advance]$ g++ -DEXPERIMENT=6 advance.cc 
[[email protected] advance]$ ./a.out 
the end 
[[email protected] advance]$ g++ -DEXPERIMENT=7 advance.cc 
[[email protected] advance]$ ./a.out 
the end 
[[email protected] advance]$ 

à partir du site sgi (voir le lien en haut), il a l'exemple suivant:

list<int> L; 
L.push_back(0); 
L.push_back(1); 

list<int>::iterator i = L.begin(); 
advance(i, 2); 
assert(i == L.end()); 

Je pense que l'affirmation devrait appliquer à d'autres types de conteneurs, non?

Qu'est-ce qui me manque?

Merci!

Répondre

2

Quand j'avancer le iterator hors de l'extrémité du récipient, ...

... vous obtenez comportement non défini. Quoi qu'il arrive alors, c'est bien selon la norme C++. Cela pourrait être much worse que des résultats incohérents.

6

Il n'y a pas de bogue dans l'algorithme d'avance STL.

Il n'est pas défini ce qui se passe si vous avancez après la fin d'une collection.

Un comportement non défini est un concept commun en C/C++, les résultats sont toujours valables pour un comportement indéfini, car ... il s'agit d'un comportement indéfini.

Vous aurez probablement un bug dans votre programme si vous faites quelque chose qui donne un comportement indéfini.

2

Vous avancez l'itérateur au-delà de la fin du conteneur. De la documentation:

Si n> 0, il est équivalent à l'exécution ++ i n fois

Vous n'avez pas 100 éléments dans le conteneur, mais que vous avancez l'itérateur 100 positions. Il ne va pas s'arrêter quand il atteint la fin du conteneur car il ne sait pas où se trouve la fin du conteneur.

0

Ce qui vous manque, c'est que dans l'exemple la liste contient exactement deux éléments. Si vous avancez depuis le début d'une liste de deux éléments par 2 étapes, vous devriez être à la fin de la liste. C'est ce que l'exemple affirme.

Si vous deviez avancer de plus de deux étapes, vous seriez dans la zone de comportement non défini, et l'assertion n'a plus aucun sens.

Questions connexes