Eclipse Fehlermeldungen



  • @Finnegan sagte in Eclipse Fehlermeldungen:

    Die wurde in einem vorherigen Beitrag in einem Link zu einem Bild gepostet.

    Ach so. Das erklärt einiges. Ich lese keinen Text in Bildern.



  • @Finnegan sagte in Eclipse Fehlermeldungen:

    Ist das korrekt? Bedenke, dass dein Array m_maxTips Elemente hat. Auf welchen Index darfst du also maximal zugreifen, damit du nicht über die Grenzen das Array hinaus schreibst?

    Index 5 ist der letzte Index .

    Aber ich bin jetzt verwirrt das mit dem einfügen vor der if Funktion🤣



  • @Programmer33 sagte in Eclipse Fehlermeldungen:

    Index 5 ist der letzte Index .

    Aber ich bin jetzt verwirrt das mit dem einfügen vor der if Funktion🤣

    Drücke diesen letzten Index mal nicht als konkrete Zahl, sondern allgemein unter Verwendung der Variablen m_maxTips aus. Schliesslich kann der Konstruktor auch mit maxTips größer 6 aufgerufen, oder das Array schonmal vergrößert worden sein.



  • Jetzt peile ich gerade wieder nichts mehr ☹
    Was meinst du genau ?



  • @Programmer33 sagte in Eclipse Fehlermeldungen:

    Jetzt peile ich gerade wieder nichts mehr ☹
    Was meinst du genau ?

    Ich versuche dich dazu anzuregen, dir selbst zu erschliessen, weshalb m_countTips > m_maxTips nicht korrekt ist, und was da stattdessen stehen muss. Du vergrößerst das Array zu spät, zu einem Zeitpunkt, wo bei einem vorherigen Aufruf des operator+= schon ein ungültiger Schreibzugriff über die Array-Grenzen hinaus stattgefunden hat.

    Im übrigen verletzt dein operator+= auch die Zusicherung 0 <= m_countTips <= m_maxTips aus dem Klassendiagramm, indem er erlaubt, dass diese Bedingung falsch wird. Diese Zusicherungen haben einen Grund, dass sie mit in Klassendiagramm stehen: Sie müssen nach dem Aufruf jeder Funktion deiner Klasse gültig sein. Ansonsten ist dein Programm nicht korrekt - und es findet ja auch tatsächlich ein ungültiger Array-Zugriff statt.

    Für so etwas gibt es übrigens in C++ auch die Funktion assert() (Englisch für Zusicherung) womit du im Debug-Modus solche Zusicherungen prüfen kannst und dein Programm dann auf einen Fehler läuft, wenn diese Zusicherungs-Bedingung nicht erfüllt ist. Du kannst das mal in dein Programm ans Ende deines operator+= vor dem return einbauen - beim Verlassen der Funktion muss die im Klassendiagramm angegebene Zusicherung schliesslich erfüllt sein:

    #include <cassert>
    
    ...
    
    CLottoTicket& CLottoTicket::operator+=(CTip tip) {
        ...
        assert(0 <= m_countTips && m_countTips <= m_maxTips);
        return *this;
    }
    

    Wenn du das drin hast, und nun in einem Test mehr Tips hinzufügst als die Kapazität (m_maxTips) des Array zulässt, wird dieses assert auf einen Fehler laufen. Damit weisst du dann, dass du in deinem operator+= irgendwo einen Programmierfehler hast. Zusicherungen/Assertions sind ein Hilfsmittel, mit dem man solche Fehler frühzeitig finden kann. Solche asserts für die im Klassendiagramm angegebenen Zusicherungen kannst du übrigens auch ruhig in dem Programm stehen lassen, wenn du es abgibst. Das macht garantiert keinen schlechten Eindruck, eher im Gegenteil.

    Nochmal: Die Ursache für diesen Fehler liegt wie gesagt in der Bedingung m_countTips > m_maxTips. Du vergrößerst das Array zu spät, nachdem schon ein ungültiger Schreibzugriff stattgefunden hat.



  • Soll ich diese Bedingung also vorher einbauen ?
    m_tips = new CTip [m_maxTips+12];

    
    CLottoTicket& CLottoTicket::operator+= (CTip tip){
    
    	m_tips = new CTip [m_maxTips+12];
    	if( m_countTips > m_maxTips ){
    
    		CTip* temp = new CTip [m_maxTips];
    
    		for(int i = 0; i < m_maxTips; i++)
    		{
    			temp[i] = m_tips[i];
    		}
    
    			delete[] m_tips;
    
    		m_tips = new CTip [m_maxTips+12];		
    for(int i = 0; i < m_maxTips; i++) {
    			m_tips[i] = temp[i];
    		  }
    
    		delete[] temp;
    		m_maxTips += 12;
    
    }
        m_tips[m_countTips++]= tip;
       return *this;
    
    }
    
    
    
    
    
    

    Jetzt ok?
    Hoffe das es jetzt passt will an einer anderen Aufgabe weiter lernen 😀



  • @Programmer33 sagte in Eclipse Fehlermeldungen:

    Soll ich diese Bedingung also vorher einbauen ?
    m_tips = new CTip [m_maxTips+12];

    WTF?

    Jetzt ok?

    Nein! Jetzt hast du ein Speicherleck und einen Zugriff auf zerstörte und freigegebene Objekte eingebaut. Weisst du überhaupt, was du tust oder schiebst du nur irgendwelche zusammenkopierte Zeilen hin- und her in der Hoffnung durch Zufall ein korrektes Programm zu erhalten?

    Ich weiss nicht, was ich noch schreiben soll. Nochmal zum mitschreiben:

    Die Bedingung m_countTips > m_maxTips, das ist das was in den Klammern hinter dem ifsteht, ist nicht korrekt. Diese Bedingung führt dazu, dass du das Array zu spät vergrößerst. Du musst es schon vorher vergrößern, und nicht erst dann, m_countTips > m_maxTips gilt.

    Das hat überhaupt nichts mit der von dir verschobenen Zeile zu tun, die vorher an der richtigen Stelle stand. Du musst also nur diese Zeile verändern:

    if( m_countTips > m_maxTips ){
    

    und zwar derart, dass der if-Block ausgeführt wird, wenn das Array zu dem Zeitpunkt des Aufrufs exakt voll ist und nicht erst dann wenn es voll ist und noch ein zusätzliches Element ausserhalb der Array-Grenzen hineingequetscht wurde.

    Das musst du nach all meinen Erklärungen hinbekommen, ansonsten kann ich dir nur ernsthaft raten, dir frühzeitig ein anderes Fach zu suchen, da ich dann Zweifel haben werde, ob du damit je glücklich wirst.

    Edit: Noch etwas zum Verständnis: Wenn ich sage du vergrößerst das Array zu spät, dann meine ich damit nicht "zu spät in der Funktion", sondern "zu spät im Ablauf des Programms". Das Vergrößern war schon an der richtigen Stelle, nur muss dieses bei einem früheren Aufruf von operator+= stattfinden. Das wird mit besagter if-Bedingung gesteuert.



  • Ah if m_maxTips == m_countNumbers

    War irgendwie total verwirrt ,dachte mein Code passt nicht.

    Hoffe das jetzt ok ist ?🤣



  • @Programmer33 sagte in Eclipse Fehlermeldungen:

    Ah if m_maxTips == m_countNumbers

    Grad aus dem Keller vom Weinen zurückgekommen. Das ich das noch erleben darf! Aber ... warum zum Henker m_countNumbers? Was ist das für eine Variable, wo kommt die her? Wenn du mit solchen Sachen irgendwann mal erfolgreich sein willst, dann musst du schon sehr sorgfältig arbeiten. Selbst bei scheinbar banalen Dingen. Ich denke die Variable sollte anders heissen.

    War irgendwie total verwirrt ,dachte mein Code passt nicht.

    Er hat auch nicht gepasst. Er wahr falsch und hat die Zusicherung verletzt. Punkt. Was man allerdings sagen konnte ist, er war einigermaßen nah dran. Das interessiert Computer allerdings nicht: Ein falsches Bit und deine Ariane 5 macht beim Start einen Looping und landet kopfüber wieder auf der Startrampe.

    Hoffe das jetzt ok ist ?🤣

    Auch wenn ich es wahrscheinlich bereuen werde: Zeig nochmal den Code, den du jetzt hast. Bis auf die if-Bedingung sah der Code weitgehend okay aus - auch wenn ich das doppelte Kopieren für schlechten Stil halte (nicht dass new/delete nicht schon schlechter Stil wären, aber dafür kannst du ja ausnahmsweise nichts). Und auch wenn ich sage es sieht "okay" aus, sehe ich auch nicht immer alles. Du solltest den Code schon selbst noch ausgiebig testen.



  • Sorry war kurz weg.
    Finnegan ich möchte sowieso kein Programmierer werden . Habe nur 1 Fach Programmierung ,dass mich verrückt macht.
    Aber da bin ich ehrlich ,da gibt es Leute die das besser machen können 😀

    Es gibt aber nur m_countNumbers ? Mit was sonst vergleichen .
    Hier mal Header und Code nochmal:

    #ifndef CLOTTOTICKET_H_
    #define CLOTTOTICKET_H_
    #include<iostream>
    #include<string>
    #include"CTip.h"
    
    class CLottoTicket{
    
    private:
        std::string m_name;
    	unsigned short m_maxTips;
    	unsigned short m_countTips = 0;
    	CTip* m_tips;
    
    public:
    	CLottoTicket(std::string name,unsigned short maxTips = 12);
    	~CLottoTicket();
    	std::string getName();
    	CLottoTicket& operator+= (CTip tip);
    	float winnings(CTip drawing,float winFor3,float winFor4,float winFor5,float winFor6);
    	void printSuccessful(CTip drawing);
    
    };
    
    
    
    
    #include<iostream>
    #include "CTip.h"
    #include "CLottoTicket.h"
    using namespace std;
    
    
    CLottoTicket::CLottoTicket(std::string name,unsigned short maxTips ){
    
    	m_name = name;
    	m_countTips = 0;
    
    
    		if (m_maxTips >= 6)
    		{
    
    			m_maxTips = maxTips;
    
    		}
    		else
    		{
    			m_maxTips = 6;
    		}
    
    		m_tips = new CTip[m_maxTips];
    
    
    }
    
    CLottoTicket::~CLottoTicket(){
    
    	delete[] m_tips;
    }
    
    
    CLottoTicket& CLottoTicket::operator+= (CTip tip){
    
    
    	if( m_countTips == m_maxTips ){
    
    		CTip* temp = new CTip [m_maxTips];
    
    		for(int i = 0; i < m_maxTips; i++)
    		{
    			temp[i] = m_tips[i];
    		}
    
    			delete[] m_tips;
    			m_tips = new CTip [m_maxTips+12];
    
    
    		for(int i = 0; i < m_maxTips; i++) {
    			m_tips[i] = temp[i];
    		  }
    
    		delete[] temp;
    		m_maxTips += 12;
    
    }
        m_tips[m_countTips++]= tip;
       return *this;
    
    }
    
    
    
    
    

    Ja bitte kontrolliere den Weg .
    Damit ich weiss ,dass der Weg richtig ist



  • Hast du auch eine konkrete Frage?



  • Finnegan wollte nochmal über den Code drüber schauen .
    Gerne können Nutzer einen schöneren Weg darstellen wie ich es besser lösen kann ?



  • @Programmer33 sagte in Eclipse Fehlermeldungen:

    Gerne können Nutzer einen schöneren Weg darstellen wie ich es besser lösen kann ?

    Was lösen? Aufgabenstellung = ?



  • Implementieren Sie den operator+=. Er fügt den als Parameter übergebenen Tipp in das Array m_tips an der nächsten freien Position ein. Falls der Tipp ungültig ist (Prüfung mit der Methode isValid() der Klasse CTip) oder kein Speicherplatz mehr frei ist, bleibt das Objekt unverändert.
    Und dann sollte man es erweitern:Erweitern Sie die Implementierung des operator+= so, dass er das Array vor dem Hinzufügen des Tipps um 12 Element vergrößert, falls kein Speicherplatz mehr vorhanden ist.

    Gerne mit Erklärung helfen



  • Okay, nicht wirklich gut, aber soweit ich das sehe, sollte es so zumindest funktionieren. Bedenke aber, dass ich nur "drübergeschaut" habe. Kompilieren und Testen musst du schon selbst.

    Ich habe auch nochmal über die Aufgabenstellung geschaut: Der Aufgabenteil

    Falls der Tipp ungültig ist (Prüfung mit der Methode isValid() der Klasse CTip) oder kein Speicherplatz mehr frei ist, bleibt das Objekt unverändert.

    ist allerdings noch nicht umgesetzt! Das ließe sich recht einfach mit einem frühzeitigen return im operator+= umsetzen. Da du den Speicherplatz allerdings bei Bedarf vergrößerst, solltest du hier stattdessen darauf testen ob du mit einem Vergrößern den Wertebereich von m_maxTips überschreitest. Bei einem unsigned shortgeht dieser von 0 bis 65535, bzw. allgemeiner von std::numeric_limits<unsigned short>::min() bis std::numeric_limits<unsigned short>::max() (dafür benötigst du ein #include <limits> oben in deiner Quellcodedatei).

    Bevor du vergrößerst, solltest du also testen, ob std::numeric_limits<unsigned short>::max() abzüglich m_maxTips größer oder gleich 12 ist. Nur dann kannst du vergrößern und 12 zu m_maxTips hinzuaddieren, ohne dass diese Variable überläuft.

    Ich würde zwei frühzeitige return empfehlen, eines in der ersten Zeile des operator+=, mit dem geprüft wird, ob der übergebene CTip gültig ist:

    if (/* CTip ist nicht gültig */)
        return *this;
    

    und eines, nachdem du dich entschieden hast, das Array zu vergrößern:

    if( m_countTips == m_maxTips ){
        if (/* Vergrößern führt zu Überlauf von m_maxTips */)
            return *this;
       ...
    

    Das sollte der Aufgabenstellung genügen.

    Bezüglich "besser lösen" habe ich schon jede Menge geschrieben, wofür dir aber scheinbar die Muße fehlte, es selbst umzustetzen:

    • Konsistente Einrückung, Leerzeichen und Leerzeilen.
    • Verwendung von Initialisierungslisten im Konstruktor (falls dir das was sagt).
    • Vermeiden des doppelten Kopierens im operator+=. Vielleicht sogar std::copy verwenden, bin mir aber unsicher ob das nicht schon zu "modern" für diese Veranstaltung ist 😉
    • Auch reicht es, im operator+=() nur die gesetzten CTip im Array zu kopieren, also nicht bis m_maxTips, sondern nur bis m_countTips.
    • Es würde einen guten Eindruck machen, wenn du die im Klassendiagramm angegebenen Zusicherungen als assert-Bedingungen einfügst, direkt am Ende der Funktionen (und vor einem eventuellen return). Diese Zusicherungen müssen nach jedem Funktionsaufruf wahr sein und solche asserts helfen dabei, eventuelle Programmierfehler vorzeitig zu erkennen.

    newund delete sind ja leider implizit Teil der Aufgabenstellung, hier einen std::vector zu nehmen ist ein Punkt, den nur euer Dozent "besser machen" könnte.



  • ok Danke für die Mühe und tipps Leute 😀


Anmelden zum Antworten