fehler bei iterator



  • hallo,

    ich habe vorher code blocks benutzt und bin auf vs umgestiegen. ich hab einnen alten code versucht zu debuggen aber in VS bekomme ich einen error. in mingW nicht

    #include <iostream>
    #include <string>
    #include <vector>
    #include <bitset>
    using namespace std;
    
    int main() {
    const size_t array_size = 10;
    vector<int> first_vec(array_size, 0);
    vector<int> second_vec(array_size, 1);
    
    for (vector<int>::iterator iter=first_vec.begin(); iter<first_vec.end(); ++iter ) {
    
    if(first_vec[*iter] != second_vec[*iter]){
        iter=first_vec.end();
        cout <<"Different";
    
    }
    else {
        if (iter==first_vec.end()-1)
    cout <<"same" << endl;
    
    }
    
    }
    
    }
    

    der error ist " cant increment iterator". ich verstehe nicht was der fehler mir sagen soll, in primer wurde mir das so beigebracht. ich hoffe ihr könnt mir helfen.

    danke



  • Wo kommt der Fehler? Beim Compilieren (in welcher Zeile?) oder während der Ausführung des Programms?

    Ansonsten ist mir nicht ganz klar, was dein Programm machen soll - du verwendest den Inhalt von first_vec als Index, um die zu vergleichenden Vektor-Element auszuwählen. Wenn du vorhast, die beiden Vektoren zu vergleichen, nimm == (oder zur Not std::compare().



  • In Zeile 15 weist du iter schon first_vec.end() zu. Danach erhöht die for-Schleife den Wert noch einmal. Visual Studio im Debugmodus achtet aber darauf, dass Iteratoren ihre Grenzen nicht verlassen. Der Code ist eigentlich korrekt, aber die Debug-"Features" machen dir einen Strich durch die Rechnung. Im Release-Modus sollte es laufen. Allerdings verstehe ich nicht, warum hier nicht einfach ein break; genutzt wird. (Im Übrigen macht der Code irgendwie keinen Sinn, na ja was solls.)

    Edit:
    Iteratoren würde man eigentlich so verwenden:

    std::vector<int> v1;
    // mit Werten füllen
    for (std::vector<int>::const_iterator i = v1.begin(); i != v1.end(); ++i)
    {
      std::cout << *i << "\n";
    }
    


  • ok danke

    ja die aufgabe war ich sollte jeden wert von zwei vectoren vergleichen. sind beide gleich und haben die selbe länge soll "same" ausgegeben werden ansonsten "different".



  • Wenn du die beiden Container vergleichen willst, dann brauchst du auch in jedem einen Iterator (oder alternativ kannst du auch einen unsigned-Wert hochzählen und als Index in beide Vektoren verwenden).



  • Wie wärs mit folgendem:

    std::cout << "v1 und v2 sind " << (v1.size() == v2.size() && std::equal(v1.begin(), v1.end(), v2.begin()) ? "" : "un") << "gleich" << std::endl;
    


  • kantaki schrieb:

    ok danke

    ja die aufgabe war ich sollte jeden wert von zwei vectoren vergleichen. sind beide gleich und haben die selbe länge soll "same" ausgegeben werden ansonsten "different".

    Wie geahnt, du hast Iteratoren noch nicht ganz verstanden. Sinnvollerweise macht man das mit Templates, aber ich verzichte mal darauf, da du die vermutlich noch nicht kennst.

    bool are_int_vectors_equal(std::vector<int>::const_iterator begin,
      std::vector<int>::const_iterator end, std::vector<int>::const_iterator compare)
    {
      for (; begin != end; ++begin, ++compare)
      {
        if (*begin != *compare)
          return false;
      }
      return true;
    }
    
    int main()
    {
      std::vector<int> v1;
      std::vector<int> v2;
      // mit Werten füllen
      if (v1.size() == v2.size() && 
        are_int_vectors_equal(v1.begin(), v1.end(), v2.begin()))
        std::cout << "equal!";
      else
        std::cout << ":S";
    }
    

    Verwendung also quasi wie bei Pointern. Siehe auch:
    http://www.cplusplus.com/reference/algorithm/equal/


  • Administrator

    cooky451 schrieb:

    In Zeile 15 weist du iter schon first_vec.end() zu. Danach erhöht die for-Schleife den Wert noch einmal. Visual Studio im Debugmodus achtet aber darauf, dass Iteratoren ihre Grenzen nicht verlassen. Der Code ist eigentlich korrekt, aber die Debug-"Features" machen dir einen Strich durch die Rechnung. Im Release-Modus sollte es laufen.

    Darf ich fragen, wie du auf die Idee kommst, dass der Code korrekt sein soll? Es steht zwar im Standard, dass es bei den Iteratoren einen Iterator hinter den gültigen Werten gibt, aber mir ist nichts davon bekannt, dass man diesen letzten Iterator weiter erhöhen darf. Ich würde eher sagen, dies ist einfach nicht spezifiziert und unterscheidet sich daher von Kompiler zu Kompiler.

    Wenn man sich die Vorbedingungen eines Input-Iteratoren im Standard anschaut, dann steht beim Inkrementieren sogar, dass der Iterator dereferenzierbar sein muss.

    Grüssli



  • hmm... ich hatte vorher nur subscript und dann wurde mir gesagt das man das selbe auch mit iterators erreichen kann.

    pointers bin ich gerade erst am lesen und functions hatte ich bisher auch nich nicht.

    #include <iostream>
    #include <string>
    #include <vector>
    #include <bitset>
    using namespace std;
    
    int main() {
    const size_t array_size = 10;
    vector<int> first_vec(array_size, 1);
    vector<int> second_vec(9, 1);
    
    for (vector<int>::iterator iter=first_vec.begin(); iter<first_vec.end(); ++iter ) {
    
    if(first_vec[*iter] != second_vec[*iter] || first_vec.size()!=second_vec.size()){
        iter=first_vec.end()-1;
        cout <<"Different";
    
    }
    else {
        if (iter==first_vec.end()-1)
    cout <<"same" << endl;
    
    }
    
    }
    
    }
    

    macht das programm nicht genau das selbe wie dein programm ? es schaut sich jede zahl an und vergleicht sie , ist sie anders oder die größe nicht identisch wird "different" ausgegeben. ansonsten "same"



  • Die Konstruktion first_vec[*iter] ist Unsinn - mit *iter bekommst du bereits das Vektor-Element, auf das der Iterator verweist - den Wert mußt du nicht noch mal an den Index-Operator übergeben (erst recht nicht an den eines anderen Vektors). Wie man es richtig macht, hat cookie schon vorgeführt (die Schleife funktioniert im Prinzip auch ohne in eine Hilfsfunktion verstaut zu werden).



  • Dravere schrieb:

    Ich würde eher sagen, dies ist einfach nicht spezifiziert und unterscheidet sich daher von Kompiler zu Kompiler.

    Da hast du vermutlich recht, ich habe unüberlegt geschrieben.



  • ok

    gesterhn hatte ich den code nch nicht verstanden 😕 aber jetzt weiß ich was er macht.

    vielen dank für die schnelle hilfe

    edit *

    eine syntaktiksche frage hätte ich noch.

    for (; begin != end; ++begin, ++compare)
    

    warum ist ein semikolon am anfang der forschleife und warum werden ++begin und ++compage mit einem komma getrennt und nicht mit einem semikolon ?



  • kantaki schrieb:

    warum ist ein semikolon am anfang der forschleife

    Der Initialisierungsteil der For-Schleife (Teil zwischen öffnender Klammer und erstem Semikolon) ist leer.

    kantaki schrieb:

    und warum werden ++begin und ++compage mit einem komma getrennt und nicht mit einem semikolon ?

    Weil du beide Anweisungen nacheinander ausführen willst. Ein Semikolon darfst du im Schleifenkopf nur zur Trennung von Initialierungs-, Bedingungs- und Update-Teil verwenden.



  • alles klar danke 🙂



  • Äh...

    #include <iostream>
    #include <vector>
    
    int main() {
      std::vector<int> a, b;
    
      std::cout << (a == b ? "gleich" : "ungleich") << std::endl;
    }
    

  • Administrator

    seldon schrieb:

    Äh...

    #include <iostream>
    #include <vector>
    
    int main() {
      std::vector<int> a, b;
    
      std::cout << (a == b ? "gleich" : "ungleich") << std::endl;
    }
    

    😮 *nachschlägt* 😮 😮
    Ich sag es immer wieder, man lernt nie aus in C++ 😃
    geht ein paar std::equal & std::lexicographical_compare vereinfachen

    Danke seldon!

    Grüssli



  • Dravere schrieb:

    seldon schrieb:

    Äh...

    #include <iostream>
    #include <vector>
    
    int main() {
      std::vector<int> a, b;
    
      std::cout << (a == b ? "gleich" : "ungleich") << std::endl;
    }
    

    😮 *nachschlägt* 😮 😮
    Ich sag es immer wieder, man lernt nie aus in C++ 😃
    geht ein paar std::equal & std::lexicographical_compare vereinfachen

    Danke seldon!

    Grüssli

    Sag bloß, das kanntest du nicht 😃

    (Ich dachte er möchte das unbedingt mir Iteratoren machen, daher meine Lösung mit equal)


Anmelden zum Antworten