2009-05-15 16 views
1

Ich habe ein Programm erstellt, und es verwendet die vector.h # include, und Iteratoren, etc ... Aber wenn ich das Programm unter bestimmten Umständen (ich versuche immer noch herauszufinden, was das wäre) Ich bekomme einen Assertion-Fehler, der mich auf Zeile 98 von vector.h verweist. Ich ging 98 von vector.h Linie und bekam dies:Was bedeutet dieser Code in "Vektor"? (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; 
      } 

Kann jemand bitte sagen Sie mir, was das bedeutet und was in meinem Programm verursacht diese Behauptung?

NB: Linie 98, für die Aufzeichnung, ist derjenige, der „_DEBUG_ERROR (“ vect ...“

NB beginnt: Dies ist der Code in meinem Programm, das ich ausgelöst, um den Fehler GLAUBEN, ich bin wenn auch nicht ganz sicher,

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

Es sollte nur #include sein, nicht vector.h, btw. – GManNickG

Antwort

10

Die Laufzeit erkennt, dass Sie einen Iterator sind dereferencing, die vor dem Beginn() oder nach dem Ende()

wenn Sie sich vorstellen, Löschen Sie das letzte Element in dem antiviral_data Vektor in Zeile 7:

aI = antiviral_data.erase(aI); 

aI-antiviral_data.end() gesetzt wird, und wenn Sie dereferenzieren es in Zeile 14:

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

und auch in Zeile 5:

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

Sie dereferenzieren einen Out-of-Bound-Iterator.

Der Fix ist zu überprüfen, dass aI != antiviral_data.end() nach dem Erase-Aufruf, um sicherzustellen, dass Sie nicht das Ende des Vektors, bevor Sie es weiter verwenden, haben.

7

Sie möchten wirklich STL-Algorithmen wie remove_if betrachten, anstatt dieses Zeug manuell zu tun.

5

Ein kleiner allgemeiner Kommentar: Verwenden Sie bei der Überprüfung eines Iterators für end() nicht "<", sondern nur "!=". So sollten die ersten Zeilen des Codes wie folgt aussehen:

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

Doch wie Josh bereits erwähnt, spezifische Fehler in Zeile 7.

+0

Darf ich fragen, warum ich "! =" Verwenden soll? –

+1

Der Operator "less than" ist nicht für alle Iteratoren definiert - siehe diese Übersicht: http://cplusplus.com/reference/std/iterator. Wie Sie sehen können, existieren die Ungleichheitsoperatoren für alle Iteratoren. Außerdem könnte der Operator "kleiner als" viel langsamer sein (er könnte von linearer Komplexität sein), verglichen mit dem Ungleichheitsoperator (der konstant ist). Und in Ihrem Fall muss nicht überprüft werden, ob Ihr Iterator 'aI' am Ende kleiner ist, sondern nur, dass Sie das Ende noch nicht erreicht haben. – beef2k

-2

ein Element in einem Vektor Löschen verlieren alle Iteratoren.

+3

Der vom Löschen zurückgegebene Iterator ist immer gültig (oder mindestens gleich end()) –

1

Neben der Antwort akzeptiert, und auf slavy13 Antwort zu erarbeiten -
(EDIT - und wie von Josh erwähnt, nicht auf diese Frage direkt relevant - Ich bin hier als Referenz zu verlassen).

Code (aber nicht dieser Code) geht manchmal davon aus, dass Sie Elemente aus einem Vektor entfernen und weiterlaufen lassen können. Dies ist eine falsche Annahme - sobald Sie ein Element aus einem Vektor entfernen, werden alle anderen Iteratoren, die dem entfernten Element folgen, für ungültig erklärt - Sie können nicht mehr davon ausgehen, dass sie korrekt sind, und "schlechte Dinge" können passieren, wenn Sie sie weiterhin verwenden.

Der Grund dafür ist, weil ein Vektor tatsächlich Informationen in einer Array-Form speichert. Wenn ein Element entfernt wird, werden alle folgenden Elemente um eine Zelle nach unten kopiert. Die Iteratoren werden nicht entsprechend aktualisiert.

Es wird dringend empfohlen, die STL-Dokumentation zu konsultieren, wenn Sie versuchen, solche Dinge zu tun, weil es durchaus möglich ist, dass ein solcher Code bei einer bestimmten Implementierung von STL versehentlich funktioniert, aber bei anderen fehlschlägt.