[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:vector

    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. Es gibt nur zwei empfehlenswerte Einsteigerbücher:

    - C++ Primer
    - Der C++ Programmierer von Ulrich Breymann

    johannes-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:vector

    Ja, 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.


Anmelden zum Antworten