2009-05-15 8 views
1

J'ai créé un programme, et il utilise le vecteur.h #include, et les itérateurs, etc ... Mais quand je lance le programme, dans certaines circonstances (j'essaie toujours de comprendre ce que seraient ces) Je reçois une erreur d'assertion qui me renvoie à la ligne 98 de vector.h. Je suis allé à la ligne 98 de vector.h et a obtenu ceci:Que signifie ce code dans "vector"? (C++)

#if _HAS_ITERATOR_DEBUGGING 
     if (this->_Mycont == 0 
      || _Myptr < ((_Myvec *)this->_Mycont)->_Myfirst 
      || ((_Myvec *)this->_Mycont)->_Mylast <= _Myptr) 
      { 
      _DEBUG_ERROR("vector iterator not dereferencable"); 
      _SCL_SECURE_OUT_OF_RANGE; 
      } 

Quelqu'un peut me dire s'il vous plaît ce que cela signifie et ce que mon programme est à l'origine de cette affirmation?

NB: Ligne 98, pour l'enregistrement, est celui qui commence « _DEBUG_ERROR (» vect ... »

NB: Voici le code dans mon programme que je CROIS déclenché l'erreur, je suis pas tout à fait sûr, bien que

CODE:..

for(aI = antiviral_data.begin(); aI < antiviral_data.end();) 
    { 
     for(vI = viral_data.begin(); vI < viral_data.end();) 
     { 
      if((*aI)->x == (*vI)->x && (*aI)->y == (*vI)->y) 
      { 
       vI = viral_data.erase(vI); 
       aI = antiviral_data.erase(aI); 
      } 
      else 
      { 
       vI++; 
      } 
     } 
     if((*aI)->x >= maxx || (*aI)->x < 0 || (*aI)->y >= maxy || (*aI)->y < 0) 
     { 
      aI = antiviral_data.erase(aI); 
     } 
     else 
     { 
      aI++; 
     } 
    } 
+8

Il devrait être juste #include , pas vector.h, btw. – GManNickG

Répondre

10

Le moteur d'exécution détecte que vous déréférencement un itérateur qui commence avant() ou après la fin()

Imaginez si vous supprimer le dernier élément dans le vecteur antiviral_data en ligne 7:

aI = antiviral_data.erase(aI); 

aI se prépare à antiviral_data.end(), et quand vous déréférencer dans la ligne 14:

if((*aI)->x >= maxx ... 

et aussi dans la ligne 5:

if((*aI)->x == (*vI)->x 

Vous déréférencer un itérateur hors limites.

Le correctif est de vérifier que aI != antiviral_data.end() après l'appel d'effacement pour s'assurer que vous n'avez pas atteint la fin du vecteur avant de continuer à l'utiliser.

7

Vous voulez vraiment regarder les algorithmes STL comme remove_if au lieu de le faire manuellement.

5

Un petit commentaire général: Lors de la vérification d'un itérateur pour end(), n'utilisez pas "<" mais seulement "!=". Ainsi, les premières lignes de votre code devrait ressembler à:

for(aI = antiviral_data.begin(); aI != antiviral_data.end();) 
{ 
    for(vI = viral_data.begin(); vI != viral_data.end();) 
    { 
    ... 

Cependant, comme Josh a déjà signalé, votre bogue spécifique est en ligne 7.

+0

Puis-je demander pourquoi je devrais utiliser "! ="? –

+1

L'opérateur "inférieur à" n'est pas défini pour tous les itérateurs. Voir cet aperçu: http://cplusplus.com/reference/std/iterator. Comme vous pouvez le voir, les opérateurs d'inégalité existent pour tous les itérateurs. De plus, l'opérateur "inférieur à" peut être beaucoup plus lent (il peut être de complexité linéaire) par rapport à l'opérateur d'inégalité (qui est constant). Et dans votre cas, il n'est pas nécessaire de vérifier si votre itérateur 'aI' est plus petit à la fin, mais seulement que vous n'avez pas encore atteint la fin. – beef2k

-2

effacer un élément dans un vecteur tous itérateurs invalident.

+3

L'itérateur retourné de erase est toujours valide (ou au moins égal à end()) –

1

En plus de la réponse acceptée, et d'élaborer sur la réponse de slavy13 -
(EDIT - et comme mentionné par Josh, pas directement pertinent à cette question - je le laisse ici pour référence). Le code (mais pas ce code) suppose parfois que vous pouvez supprimer des éléments d'un vecteur et continuer à itérer. C'est une fausse supposition - une fois que vous supprimez un élément d'un vecteur, tous les autres itérateurs suivant l'élément supprimé sont invalidés - vous ne pouvez plus supposer qu'ils sont corrects, et de "mauvaises choses" peuvent arriver si vous continuez à les utiliser.La raison de ceci est qu'un vecteur stocke réellement des informations sous forme de tableau. Lorsqu'un élément est supprimé, tous les éléments suivants sont copiés une cellule vers le bas. Les itérateurs ne sont pas mis à jour en conséquence.

Il est fortement recommandé de consulter la documentation STL chaque fois que vous essayez de faire de telles choses, car il est tout à fait possible qu'un tel code fonctionne accidentellement sur une certaine implémentation de STL mais échoue sur d'autres.