[VS2008] Debug Assertion Failed!
-
Moin,
ich habe mir ein Programm zur Mittelwertsberechnung mit Hilfe eines Buches geschrieben:
#include <iostream> #include <vector> using namespace std; int main() { vector<double> werte(10); cout << "Ende mit e" << endl << endl; int anzahl = 0; char c; do { cout << "Geben sie den " << (anzahl+1) << ". Messert ein: "; c = cin.peek(); if (cin.peek() != 'e') { cin >> werte[anzahl]; char cend = cin.get(); anzahl++; } } while (c != 'e'); double summe = 0; double mittelwert = 0; for(int i = 0; i < anzahl; i++) summe += werte[i]; mittelwert = summe/anzahl; cout << endl; cout << "Mittelwert = " << mittelwert; }
Testweise wurden diese Werte verwendet:
5 6 5 6 54658 979435435 15848 4843546 3546549 335463546 984651
Bei der Eingabe vom letzten Wert allerdings kommt es zu folgender Fehlermeldung:
--------------------------- Microsoft Visual C++ Debug Library --------------------------- Debug Assertion Failed! Program: ...o 2008\Projects\Mittelwert_vector\Debug\Mittelwert_vector.exe File: c:\programme\microsoft visual studio 9.0\vc\include\vector Line: 779 Expression: vector subscript out of range For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts. (Press Retry to debug the application) --------------------------- Abbrechen Wiederholen Ignorieren ---------------------------
Näher eingrenzen konnte ich das "Problem" auch schon:
- Ändere ich
vector<double> werte(10);
in
vector<double> werte(12);
funktioniert es mit den 11 Werten
- Gebe ich aber bei der neuen Definition 13 Werte ein, erscheint genau die selbe Fehlermeldung
Woran könnte das liegen?
Ich hab den Code noch nicht mit anderen Compilern außer dem VS2008 probiert.
-
na, das ist doch logisch. er sagt dir sogar woran es liegt:
Expression: vector subscript out of range.
Du greifst außerhalb der gültigen Reichweite zu. Mit vector<double> werte(10); reservierst du zehn Doubles. Und wenn du mit dem Index 10 zugreifst, bist du außerhalb der reservierten zehn. Denn in C++ zählt man ab Null! 0 bis 10 ergibt 11 Werte. Und 11 > 10.
-
vector<double> vec(10); // 10 Doubles vec[0] = 5; // auf den ersten (Index 0) zugreifen vec[1] = 5; // auf den zweiten (Index 1) zugreifen ... vec[10] = 5; // auf den elften (Index 10) zugreifen. PENG!
-
Moin,
Wenn ich mal mein Buch zitieren darf:
[...]Im Unterschied zu einem gewöhnlichen Array kann ein Container dynamisch wachsen.
[...]
2. Erzeugen Sie einen vector-Container für double-Daten:vector<double> messwerte(20)
Der Wert in den Runden Klammern gibt an, dass der Container anfangs Platz für 20 Datenelemente haben soll. [...] Und wenn mehr als 20 Werte eingegeben werden, passt sich der Container automatisch an.
Ich verstehe das so, dass wenn ich im Beispiel den 21. Wert eingebe, "wächst" der Container automatisch/dynamisch mit.
Ich hab mal den Beispielquelltext getestet. Gleiches Verhalten wie bei mir. Heißt das, dass das Buch in diesem Punkt für die Tonne ist?
-
Ich kenne dein Buch nicht. Aber ich vermute mal, du hast nicht alles zitiert. Das sich der Vector autom. nach Bedarf vergrößert stimmt. Aber der Vector wächst nur mit, wenn man Elemente anhängt! Im Falle von Vector mittels
push_back
Memberfunction!In deinem Zitat kann ich auch nicht erkennen, das das Buch sagt, das der Vector bei einem Index-Zugriff wächst. Es steht nur, das er wächst, wenn mehr benötigt wird.
Es ist ja auch nicht unbedingt gewollt, das der Vector autom. wächst, nur weil man mal einen falschen Indexzugriff macht. Du kannst aber natürlich solche Fehlzugriffe mittels try-catch abfangen. In deinem Buch gibt es bestimmt ein Kapitel über Exceptions.Es ist wichtig die genaue Spezifikation solcher Klassen zu lesen.
-
Moin,
Artchi schrieb:
Aber der Vector wächst nur mit, wenn man Elemente anhängt! Im Falle von Vector mittels
push_back
Memberfunction!Stimmt, das hatte ich auch 2 Seiten weiter hinten gelesen. Die Beschreibung des Beispielquelltext sagt nicht aus, dass ich den
vector
manuell vergrößern muss.Artchi schrieb:
In deinem Zitat kann ich auch nicht erkennen, das das Buch sagt, das der Vector bei einem Index-Zugriff wächst. Es steht nur, das er wächst, wenn mehr benötigt wird.
Entsprechender Quelltext, der unmittelbar auf die These folgte, noch bevor
push_back
erwähnt wurde:#include <iostream> #include <vector> using namespace std; int main() { // Container erzeugen vector<double> messwerte(20); // Messwerte einlesen cout << endl; cout << " *** Zum Beenden der Eingabe e eintippen *** " << endl << endl; int anzahl = 0; char c; do { cout << " Geben Sie den " << (anzahl+1) << ". Messwert ein: "; c = cin.peek(); if (cin.peek() != 'e') { cin >> messwerte[anzahl]; char cend = cin.get(); anzahl++; } } while (c != 'e'); // Mittelwert berechnen und ausgeben double mittelwert = 0; double summe = 0; for(int i = 0; i < anzahl; ++i) summe += messwerte[i]; mittelwert = summe/anzahl; cout << endl; cout << " Der Mittelwert betraegt: " << mittelwert << endl; cout << endl; return 0; }
Das Buch ist übrigens "Jetzt lerne ich C++".
Artchi schrieb:
Es ist ja auch nicht unbedingt gewollt, das der Vector autom. wächst, nur weil man mal einen falschen Indexzugriff macht. Du kannst aber natürlich solche Fehlzugriffe mittels try-catch abfangen. In deinem Buch gibt es bestimmt ein Kapitel über Exceptions.
Da geb ich dir recht. Wer weiß, wo das noch hinführen würde... Exceptions gibt es zwar im Buch, waren bis jetzt aber noch nicht Thema
Artchi schrieb:
Es ist wichtig die genaue Spezifikation solcher Klassen zu lesen.
Das hab ich (dummerweise) nicht getan, wollt erstmal nur mit dem Buch lernen (auch ein Fehler )
-
johannes-h schrieb:
Artchi schrieb:
In deinem Zitat kann ich auch nicht erkennen, das das Buch sagt, das der Vector bei einem Index-Zugriff wächst. Es steht nur, das er wächst, wenn mehr benötigt wird.
Entsprechender Quelltext, der unmittelbar auf die These folgte, noch bevor
push_back
erwähnt wurde:Ich habe den Quellcode nur überflogen... im Prinzip ist das Progrämmchen einfach nicht benutzerfreundlich. Nach dem Motte: "Wenn der User mehr als 20 Werte eingibt, ist halt Sense." Kein guter Stil. Und für einen Anfänger wirklich verwirrend.
Besser wäre es gewesen, wenn das Beispiel mit einem leeren Vector angefangen hätte, und nach jeder Eingabe mit push_back vergörßert worden wäre. Schau dir mal mein Beispiel an:
http://www.kharchi.eu/wiki/doku.php?id=cpp:std:vectorjohannes-h schrieb:
Das Buch ist übrigens "Jetzt lerne ich C++".
Von Markt & Technik? Die Bücher waren in den 80er Jahren gut. Heute sind sie es nicht mehr. Es gibt nur zwei empfehlenswerte Einsteigerbücher:
- C++ Primer
- Der C++ Programmierer von Ulrich Breymannjohannes-h schrieb:
Artchi schrieb:
Es ist wichtig die genaue Spezifikation solcher Klassen zu lesen.
Das hab ich (dummerweise) nicht getan, wollt erstmal nur mit dem Buch lernen (auch ein Fehler )
Nein, Fehler zu machen ist nicht verkehrt. Denn aus Fehlern lernt man! Es ist richtig erstmal allgemein etwas über die C++ Container (vector, list, map usw.) zu erfahren. Aber danach sollte man sich genauer mit deren Eigenheiten (Spezifikation) beschäftigen. Aber ein Einsteiger muß nicht gleich alle Einzeilheiten kennen.
Die Exceptions z.B. mußt du jetzt auch noch nicht kennen. Du kannst nicht alles auf einmal lernen.
-
Hallo,
Artchi schrieb:
Und für einen Anfänger wirklich verwirrend.
Hab ich gemerkt
Artchi schrieb:
Besser wäre es gewesen, wenn das Beispiel mit einem leeren Vector angefangen hätte, und nach jeder Eingabe mit push_back vergörßert worden wäre. Schau dir mal mein Beispiel an:
http://www.kharchi.eu/wiki/doku.php?id=cpp:std:vectorJa, dein Beispiel ist deutlich sinvoller/logischer/verständlicher. Und es funktioniert auch ;).
Artchi schrieb:
johannes-h schrieb:
Das Buch ist übrigens "Jetzt lerne ich C++".
Von Markt & Technik? Die Bücher waren in den 80er Jahren gut. Heute sind sie es nicht mehr.
Ja, das Buch ist von M&T. Warum sind die Bücher heute nicht mehr so gut? (Mein einziger Anhaltspunkt wäre, dass der genannte Code für die Tonne ist...)
Ich werde mich dann mal nach den geannten Büchern umsehen.