2016-06-04 7 views
3

Ich habe einen kurzen Code geschrieben, der eine while-Schleife verwendet, um durch einen (sortierten!) Vektor von Strukturen und fügt ein neues Element basierend auf seinem Preis (wenn es bereits ist ein Eintrag für einen bestimmten Preis, der neue Eintrag sollte hinter dem bestehenden Eintrag eingefügt werdenDebug Assertion fehlgeschlagen Visual Studio 2015: Vektor Iterator nicht dereferencable

Mit g++ und Sublime Text 3 funktioniert alles (Ausgabe am Ende dieser Frage), aber mit Visual Studio 2015 erhalte ich den Fehler: Debug Assertion Failed! ... Expression: vector iterator not dereferencable. (Beachten Sie, dass dieser Fehler nur auftritt, wenn das neue Element am Ende des vorhandenen Vektors angehängt werden soll. Wenn wir das neue Element in struc newEl = {5, 2.0} ändern, funktioniert alles sowohl mit VS als auch mit g++.)

Der Code sieht wie folgt aus:

#include <iostream> 
#include <vector> 

struct struc { 
    int num; 
    double price; 
}; 

int main() { 
    std::vector<struc> v = { { 1, 1.5 },{ 2, 1.6 },{ 3, 2 },{ 4, 2.6 } }; 
    struc newEl = { 5, 2.7 }; 

    std::vector<struc>::iterator it = v.begin(); 

    while (((*it).price <= newEl.price) && (it < v.end())) { 
     it++; 
    } 

    v.insert(it, newEl); 

    for (struc vec : v) { 
     std::cout << vec.num << ", " << vec.price << std::endl; 
    } 

    std::cout << "Finished"; 
    return 0; 
} 

Der Ausgang (und im Fall von g++ und ST) sein sollte:

1, 1.5 
2, 1.6 
3, 2 
4, 2.6 
5, 2.7 
Finished 

Jetzt ist meine Frage, was bewirkt, dass der Fehler in VS und was muss ich ändern, damit es in VS funktioniert?

Vielen Dank!

Antwort

6
while (((*it).price <= newEl.price) && (it < v.end())) { 

Sie müssen prüfen, ob Sie am Ende vor sind dereferenzieren Sie Iterator und prüfen Sie den Wert:

while ((it!=v.end()) && (it->price <= newEl.price)) { 

Ansonsten sind Sie im Grunde Sie garantiert werden dereferenzieren der end Iterator, das ist genau das, was du vermeiden willst.

(Sie können < nicht für die meisten Typen von Iteratoren verwenden, daher ist das Überprüfen der Schleife mit != eine gängige Praxis).

Sie können sich bewusst sein, dass && "Kurzschlüsse" so, wenn die erste Bedingung false ist, wird die zweite nicht einmal überprüft. Dies wird durch die Sprache garantiert (es sei denn, einige Idioten Überlasten operator&&, aber das ist Gott sei Dank selten, weil es so eine schlechte Idee ist). Deshalb ist meine Version sicher.

Nun löst dieser Fehler Undefined Behaviour - der Fehler liegt bei Ihnen! Die Sprache versucht nicht einmal, dir zu helfen, und alles kann passieren. Ihr Programm könnte abstürzen, es könnte normal funktionieren, es könnte jedes andere Mal funktionieren, oder es könnte Ihren Laptop in eine rosa Giraffe verwandeln. C++ Trades sind nett zu dir, anstatt schnell zu sein.

Ich weiß, dass die Microsoft-Implementierung im Debug-Modus checked iterators hat, die Ihren Fehler hier auf Kosten von immer überprüfen. Im Release-Modus würde dies nicht passieren.

Ich habe es nicht verwendet, aber nach this answer, GCC hat etwas ähnliches.


(Als Nebenwirkung, halte ich wirklich nutzen std::endl schlechte Praxis sein. Here's why. Einige Leute auf, dass bei mir nicht einverstanden ist. Darüber lernen und Ihre eigene Entscheidung treffen, nehme ich an.)

+0

Das löst das Problem. Danke auch für die idiotensichere Erklärung (die ich verstehen kann).Weißt du, warum ST + 'g ++' funktioniert, während VS nicht? – David

+0

@David Ich habe meine Antwort ein wenig konkretisiert. – BoBTFish

+0

Wunderbar, ich habe gerade Ihren Blog gelesen und bin Ihrer Bemerkung mit 'std :: endl' begegnet. Ich werde mir das merken! Nochmals vielen Dank für die gründliche Antwort! – David

Verwandte Themen