vector iterators incompatible

vector iterators incompatible - C++ - Programmation

Marsh Posté le 08-02-2010 à 11:19:19    

Salut,
 
J'ai des librairies C++ qui avaient été faite sous Linux et compilées à GCC.
J'ai enfin réussi à les compiler sous VisualStudio mais lors de l'exécution d'un des tests, j'ai l'erreur suivante : vector iterators incompatible.
http://i1007.photobucket.com/album [...] /error.png
 
Je n'ai absolument aucune idée du problème. J'avoue que je reste perplexe quant aux résultats de mes recherches sur le web pour trouver une explication.
 
Si je regarde un peu dans le code, je trouve des choses comme ça :

Code :
  1. for (vector<AnnotatedArc *>::iterator iter = ptrDownstreamArcs->begin ();
  2.        iter != ptrDownstreamArcs->end ();
  3.        ++iter)
  4.   {


 
Avez-vous une idée de ce qui ne plait pas à VS ?
Sous Linux/GCC 4.3, mon test passe sans problème.
 
Si qq'un a une idée, une piste ou une explication, je suis preneur ...
 
Merci de votre aide.

Reply

Marsh Posté le 08-02-2010 à 11:19:19   

Reply

Marsh Posté le 08-02-2010 à 15:02:40    

Le probleme n'est pas dans ce que tu montres.  Tu compares vraisemblablement deux iterateurs sur des conteneurs differents, ou peut-etre avec un iterateur invalide.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 08-02-2010 à 15:08:08    

Un Programmeur a écrit :

Le probleme n'est pas dans ce que tu montres.  


ok.
 
 

Un Programmeur a écrit :

Tu compares vraisemblablement deux iterateurs sur des conteneurs differents


Serait-ce un problème de template ? pourquoi alors mon test passe sous gcc ? y a t il une utilisation différente des templates sous VS ?
 

Un Programmeur a écrit :

ou peut-etre avec un iterateur invalide


Ca voudrait dire quoi un itérateur invalide ?
Des manipulations sur le vecteur qui ne sont pas permises ?
 
Merci de votre aide

Reply

Marsh Posté le 08-02-2010 à 15:30:24    

greenzephyr a écrit :


Serait-ce un problème de template ?


 
Tu ne montres pas de template...
 

Citation :

pourquoi alors mon test passe sous gcc ? y a t il une utilisation différente des templates sous VS ?
 


 
Comportement indefini, ca fait n'importe quoi.  Y compris ce a quoi tu t'attends.  Est-ce que tu as essaye avec la version de la lib de gcc qui fait des verifs?
 

greenzephyr a écrit :


Ca voudrait dire quoi un itérateur invalide ?


 
p.e. un iterateur qui n'a pas ete initialise, ou bien dont le conteneur a ete detruit, ou l'element qui est "pointe" par l'iterateur a ete detruit...
 


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 08-02-2010 à 15:42:13    

Tu ne montres pas de template...


Je parle de la classe vector de la lib STL :

Code :
  1. template<class _Ty, class _Ax> class vector : public _Vector_val<_Ty, _Ax>


Je me dis que j'ai peut-être un problème avec ca ...
 

Comportement indefini, ca fait n'importe quoi.  Y compris ce a quoi tu t'attends.  Est-ce que tu as essaye avec la version de la lib de gcc qui fait des verifs?


De quelle version de gcc parles-tu ?  
Pour info, les librairies que j'utilise existent et sont utilisées depuis plusieurs années sous Linux/gcc. Je pars du principe que c'est ok sous cet environnement là.
Mais si je peux faire un test pour en assurer grace à ta "version de gcc qui fait des vérifs", ce se tente... car faut bien que je trouve le bug ;-)
 

p.e. un iterateur qui n'a pas ete initialise, ou bien dont le conteneur a ete detruit, ou l'element qui est "pointe" par l'iterateur a ete detruit...


Je continue l'enquête pour essayer de trouver le problemem mais c'est pas gagné  :(  
 
Je reste connecté au fofo, si vous avez des idées ...  
 
merci de ton aide "Un programmeur" car y a pas foule aujourd'hui ....

Reply

Marsh Posté le 08-02-2010 à 15:45:39    

Et tu ne peux pas nous donner la portion de code où ça plante ?


---------------
Be the one with the flames.
Reply

Marsh Posté le 08-02-2010 à 15:49:32    

Riot a écrit :

Et tu ne peux pas nous donner la portion de code où ça plante ?


Je passe en debug et dès que j'ai ciblé précisemment les lignes qui posent problème, je post.
Mais j'avoue que je suis pas super efficace, c'est pas mon code, je connais pas les libs ... bref je débute avec ces librairies...
 
Je reviens asap avec du code a vous mettre sous la dent.

Reply

Marsh Posté le 08-02-2010 à 16:17:23    

greenzephyr a écrit :

Je me dis que j'ai peut-être un problème avec ca ...


Commence par te dire qu'il y a un probleme dans ton code.  C'est beaucoup plus vraisemblable.
 

Citation :

Comportement indefini, ca fait n'importe quoi.  Y compris ce a quoi tu t'attends.  Est-ce que tu as essaye avec la version de la lib de gcc qui fait des verifs?


De quelle version de gcc parles-tu ?


 
http://gcc.gnu.org/onlinedocs/libs [...] _mode.html


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 08-02-2010 à 16:20:55    

Un Programmeur a écrit :


Commence par te dire qu'il y a un probleme dans ton code.  C'est beaucoup plus vraisemblable.
 

Citation :

Comportement indefini, ca fait n'importe quoi.  Y compris ce a quoi tu t'attends.  Est-ce que tu as essaye avec la version de la lib de gcc qui fait des verifs?


De quelle version de gcc parles-tu ?


 
http://gcc.gnu.org/onlinedocs/libs [...] _mode.html


 
ok merci. Bien noté.
Je vais tenter le mode debug dont tu parles.
 
merci

Reply

Marsh Posté le 16-02-2010 à 10:59:32    

salut
Après une courte pause sur d'autres projets tout autant réjouissant, je reviens sur mon problème.
 
Je viens apporter un complément d'information qui j'espère vous donnera des idées sur  le problème que je rencontre.
 
Bon, j'ai toujours l'erreur "vector iterators incompatible". J'ai localisé le plantage.
 
Il y a dans le code un test != entre 2 objets de classe std::_Vector_const_iterator<Arc,std::allocator<Arc> >, où Arc est une classe de la librairie.
Ca plante donc sur l'opérateur != de _Vector_const_iterator (fichier c:\Program Files\Microsoft Visual Studio 9.0\VC\include\vector)
Le test est :

Code :
  1. if (crossing != toBeTested)


 
Un watch sur crossing me donne:

-  crossing {axe_={...} cos_=-0.087155742747658235 sin_=0.99619469809174555 ...} std::_Vector_const_iterator<Arc,std::allocator<Arc> >
 -  ptr {axe_={...} cos_=-0.087155742747658235 sin_=0.99619469809174555 ...} Arc
 +  axe_ {x_=-0.50000000000000011 y_=-0.00000000000000000 z_=-0.86602540378443860 } Vecteur3<double>
   cos_ -0.087155742747658235 double
   sin_ 0.99619469809174555 double
   angle_ 1.6580627893946132 double
 +  deb_ {x_=1.2490009027033011e-016 y_=-0.99492302985782377 z_=0.10063878307356444 } Vecteur3<double>
 +  fin_ {x_=6.9388939039072284e-018 y_=0.99492302985782377 z_=0.10063878307356451 } Vecteur3<double>
 +  u_ {x_=-0.043577871373829000 y_=-0.99492302985782377 z_=0.025159695768391069 } Vecteur3<double>
 +  v_ {x_=-0.86162861866705887 y_=0.050319391536782124 z_=0.49746151492891200 } Vecteur3<double>
 +  w_ {x_=0.043577871373829125 y_=0.00000000000000000 z_=0.075479087305173373 } Vecteur3<double>
   balayage_ 3.0405264385097688 double


 
Un watch sur toBeTested me donne:

-  toBeTested {axe_={...} cos_=2.2459367226747943e-299 sin_=6.4615620656525586e-308 ...} std::_Vector_const_iterator<Arc,std::allocator<Arc> >
 -  ptr {axe_={...} cos_=2.2459367226747943e-299 sin_=6.4615620656525586e-308 ...} Arc
 +  axe_ {x_=-2.5301711256524607e-098 y_=-2.6569838326172271e+303 z_=0.00000000000000000 } Vecteur3<double>
   cos_ 2.2459367226747943e-299 double
   sin_ 6.4615620656525586e-308 double
   angle_ -2.6569842580370804e+303 double
 +  deb_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
 +  fin_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
 +  u_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
 +  v_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
 +  w_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
   balayage_ -2.6569842580370804e+303 double


 
Dans la classe _Vector_const_iterator:

Code :
  1. template<class _Ty, class _Alloc> class _Vector_const_iterator{
  2. .....
  3. bool operator!=(const _Myt& _Right) const
  4. { // test for iterator inequality
  5.  return (!(*this == _Right));
  6. }
  7. ....
  8. };


 
Un watch sur *this:

-  *this {axe_={...} cos_=-0.087155742747658235 sin_=0.99619469809174555 ...} const std::_Vector_const_iterator<Arc,std::allocator<Arc> >
 -  ptr {axe_={...} cos_=-0.087155742747658235 sin_=0.99619469809174555 ...} Arc
  +  axe_ {x_=-0.50000000000000011 y_=-0.00000000000000000 z_=-0.86602540378443860 } Vecteur3<double>
    cos_ -0.087155742747658235 double
    sin_ 0.99619469809174555 double
    angle_ 1.6580627893946132 double
  +  deb_ {x_=1.2490009027033011e-016 y_=-0.99492302985782377 z_=0.10063878307356444 } Vecteur3<double>
  +  fin_ {x_=6.9388939039072284e-018 y_=0.99492302985782377 z_=0.10063878307356451 } Vecteur3<double>
  +  u_ {x_=-0.043577871373829000 y_=-0.99492302985782377 z_=0.025159695768391069 } Vecteur3<double>
  +  v_ {x_=-0.86162861866705887 y_=0.050319391536782124 z_=0.49746151492891200 } Vecteur3<double>
  +  w_ {x_=0.043577871373829125 y_=0.00000000000000000 z_=0.075479087305173373 } Vecteur3<double>
    balayage_ 3.0405264385097688 double


 
Un watch sur _Right:

-  _Right {axe_={...} cos_=2.2459367226747943e-299 sin_=6.4615620656525586e-308 ...} const std::_Vector_const_iterator<Arc,std::allocator<Arc> > &
 -  ptr {axe_={...} cos_=2.2459367226747943e-299 sin_=6.4615620656525586e-308 ...} Arc
  +  axe_ {x_=-2.5301711256524607e-098 y_=-2.6569838326172271e+303 z_=0.00000000000000000 } Vecteur3<double>
    cos_ 2.2459367226747943e-299 double
    sin_ 6.4615620656525586e-308 double
    angle_ -2.6569842580370804e+303 double
  +  deb_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
  +  fin_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
  +  u_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
  +  v_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
  +  w_ {x_=-2.6569842580370804e+303 y_=-2.6569842580370804e+303 z_=-2.6569842580370804e+303 } Vecteur3<double>
    balayage_ -2.6569842580370804e+303 double


 
Je comprends toujours pas ce qui le dérange :(
Quelqu'un aurait-il une idée ????
 
En attendant, je repasse sous Linux, suivre les conseils de Un Programmeur et voir si je trouve qq  chose de louche...
 
Please, help me !!!
Merci de votre aide

Reply

Marsh Posté le 16-02-2010 à 10:59:32   

Reply

Marsh Posté le 16-02-2010 à 11:13:33    

c'est fou ... autant de posts et toujours pas un bout de code à regarder ... Poste le corps de la fonction où ton erreur arrive, pas juste une ligne de comparaison avec des variables qui viennent d'on ne sait où


---------------
last.fm
Reply

Marsh Posté le 16-02-2010 à 11:23:57    

theshockwave a écrit :

c'est fou ... autant de posts et toujours pas un bout de code à regarder ... Poste le corps de la fonction où ton erreur arrive, pas juste une ligne de comparaison avec des variables qui viennent d'on ne sait où


Milles excuses ... voici du code, celui de la fonction appelante :

Code :
  1. void
  2. Field::firstCrossing (Arc *ptrArc, Loop::const_iterator *ptrCrossing) const
  3.   throw (CantorErreurs)
  4. {
  5.   // find the first crossing
  6.   VecDBL v1, v2;
  7.   int nbInt;
  8.   Loop::const_iterator crossing = boundary_.begin ()->end ();
  9.   for (Boundary::const_iterator i = boundary_.begin ();
  10.        i != boundary_.end ();
  11.        ++i)
  12.     for (Loop::const_iterator j = i->begin (); j != i->end (); ++j)
  13.     {
  14.       ptrArc->intersection (*j, &nbInt, &v1, &v2);
  15.       if (nbInt > 0)
  16.       {
  17.         *ptrArc = Arc (ptrArc->debut (), v1);
  18.         crossing = j;
  19.       }
  20.     }
  21.   Loop::const_iterator toBeTested = boundary_.begin ()->end ();
  22.   // verify we stay away from the vertices
  23.   if (crossing != toBeTested)
  24.   {
  25.     if ((ptrArc->fin ().angleAvecVecteur(crossing->debut ()) > small)
  26.         && (ptrArc->fin ().angleAvecVecteur(crossing->fin   ()) > small))
  27.       *ptrCrossing = crossing;
  28.   }
  29. }


 
Au passage, il s'agit d'une bibliothèque gratuite du CNES, nommée Marmottes: http://logiciels.cnes.fr/MARMOTTES/fr/logiciel.htm


Message édité par greenzephyr le 16-02-2010 à 11:27:37
Reply

Marsh Posté le 16-02-2010 à 12:10:03    

dans le cas où boundary_ est un vecteur vide, je ne sais pas ce qui se passe, ce ne serait pas ce cas-là que tu rencontres ?


---------------
last.fm
Reply

Marsh Posté le 16-02-2010 à 12:15:27    

theshockwave a écrit :

dans le cas où boundary_ est un vecteur vide, je ne sais pas ce qui se passe, ce ne serait pas ce cas-là que tu rencontres ?


Non, je ne pense pas puisque toBeTested peut être récupéré (et non vide) :

Code :
  1. Loop::const_iterator toBeTested = boundary_.begin ()->end ();


+  toBeTested {axe_={...} cos_=2.2459367226747943e-299 sin_=6.4615620656525586e-308 ...} std::_Vector_const_iterator<Arc,std::allocator<Arc> >

Reply

Marsh Posté le 16-02-2010 à 12:44:17    

end() renvoie un iterateur non-valide (c'est son comportement), donc non.


Message édité par Riot le 16-02-2010 à 12:44:32

---------------
Be the one with the flames.
Reply

Marsh Posté le 16-02-2010 à 14:21:36    

là, comme ca, je ne crois pas voir d'erreur flagrante, donc, mise à part le fait que tu assumes que boundary_ contient au moins un élément.
 
Attention aux effets de bord peut-être ? Est-ce que modifier ptrArc (intersection, affectation d'une nouvelle valeur) ne va pas invalider tes itérateurs ?


---------------
last.fm
Reply

Marsh Posté le 16-02-2010 à 14:25:45    

theshockwave a écrit :

là, comme ca, je ne crois pas voir d'erreur flagrante, donc, mise à part le fait que tu assumes que boundary_ contient au moins un élément.
 
Attention aux effets de bord peut-être ? Est-ce que modifier ptrArc (intersection, affectation d'une nouvelle valeur) ne va pas invalider tes itérateurs ?


 
C'est exactement ce sur quoi j'enquete car j'ai lu 2,3 postes (http://objectmix.com/c/738852-ques [...] tor-t.html, http://objectmix.com/c/708702-quer [...] ector.html) qui me font penser qu'un truc doit changer  dans le vecteur qui fout l'itérateur en l'air ....
 
Mais que c'est hard à trouver ....

Reply

Marsh Posté le 17-02-2010 à 08:49:32    

23.  Loop::const_iterator toBeTested = boundary_.begin ()->end ();


 
Tu récupère l'itérateur de fin de la première liste contenue dans boundary_ or crossing peut appartenir a n'importe laquelle de ces listes.
Comparer un itérateur d'une liste avec un itérateur d'une autre liste est un comportement indéfini.

Reply

Marsh Posté le 17-02-2010 à 09:12:20    

Tarabiscote a écrit :

23.  Loop::const_iterator toBeTested = boundary_.begin ()->end ();


 
Tu récupère l'itérateur de fin de la première liste contenue dans boundary_ or crossing peut appartenir a n'importe laquelle de ces listes.
Comparer un itérateur d'une liste avec un itérateur d'une autre liste est un comportement indéfini.


Pourrais-tu détailler un peu ta réponse stp car je vois pas bien le "Comparer un itérateur d'une liste avec un itérateur d'une autre liste est un comportement indéfini." ?
 
Et une autre question, si ce type de comparaison n'est pas autorisé en C++, pourquoi les tests passent avec succès sous GCC ?
 
 
Merci


Message édité par greenzephyr le 17-02-2010 à 09:26:52
Reply

Marsh Posté le 17-02-2010 à 09:43:40    

Parce qu'un comportement indefini ca peut etre n'importe quoi.  Y compris ce a quoi tu t'attends du moins jusqu'a la demo devant le client.
 
VC++ a un mode de validation qui detecte le probleme et te l'indique.  g++ a un mode de validation capable de detecter ce genre de probleme mais tu ne l'utilises pas.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 17-02-2010 à 10:43:43    

ok donc j'imagine que désactiver SECURE_SCL et _HAS_ITERATOR_DEBUGGING pour faire passer mon test est une très mauvaise idée .... :o  :o  :o  
 
J'ai fait le test sous Linux/GCC avec l'option _GLIBCXX_DEBUG ... et devinez ...

/usr/include/c++/4.4/debug/safe_iterator.h:218:error: attempt to increment  
    a past-the-end iterator.
 
Objects involved in the operation:
iterator "this" @ 0x0xbfb5c1b0 {
type = N11__gnu_debug14_Safe_iteratorINSt6__norm14_List_iteratorI3ArcEENSt7__debug4listIS3_SaIS3_EEEEE (mutable iterator);
  state = past-the-end;
  references sequence with type `NSt7__debug4listI3ArcSaIS1_EEE' @ 0x0xbfb5c1b0
}
Abandon


 
Donc y a bien un petit problème ...

Reply

Marsh Posté le 17-02-2010 à 14:48:14    

Je vais détailler un peu.
 
Par exemple avec le cas des vectors, on pourrait très bien utiliser pour l'itérateur de fin un pointeur pointant après le dernier élément d'un tableau utilisé en interne pour stocker les éléments.
Les deux vecteurs n'ayant pas les mêmes tableaux internent, les pointeurs ne peuvent donc pas être comparés.
 
On pourrait tout aussi bien stocker dans l'itérateur une valeur NULL en arrivant à la fin d'un tableau, ce qui rendrait l'itérateur de fin indépendant du vector.
 
Ce ne sont que des exemples simplifiés d'implémentation mais j'espère que tu comprendras un peu mieux ce que peut être un comportement indéfini.

Reply

Marsh Posté le 17-02-2010 à 15:09:33    

ouep, je commence à voir le blème... un doc intéressant (enfin pour moi, qui m'a permis de me rendre compte du problème :http://www.osl.iu.edu/publications [...] GrSc02.pdf)
 
(Edit: lien précédent corrumpu)


Message édité par greenzephyr le 17-02-2010 à 15:12:53
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed