Massives Problem: Laufzeitfehler!



  • Okay, es müsste

    int found[3]
    

    heißen um 3 Einträge zu haben. Nämlich found[0], found[1] und found [2]. Ändert aber nix am Fehler



  • Mathias1986 schrieb:

    Okay, es müsste

    int found[3]
    

    heißen um 3 Einträge zu haben. Nämlich found[0], found[1] und found [2]. Ändert aber nix am Fehler

    Was ist denn Deiner Meinung nach der Inhalt von z.B. found[1] und found[2] , und was meinst Du, was std::string::substr tut, wenn Du es mit diesen Inhalten fütterst?



  • Also die ersten paar Zeilen funktioniert es ja. Bis Zeile 5 liest er ein, deswegen kann das Ganze so falsch nicht sein (mir ist klar dass das alles wahrscheinlich viel zu kompliziert gemacht ist, aber das ist ja erstmal egal)

    found gibt mir in der Zeile die Stelle an, wo das Semikolon ist, was auch funktioniert in einem Test. Und substring gibt mir dann den String zwischen den Semikolons was für die ersten 5 Zeilen auch wunderbar funktioniert. Nur dann kommt dieser STATUS_ACCESS_VIOLATION Fehler bei der Ausführung der mir total rätselhaft erscheint.


  • Mod

    Mathias1986 schrieb:

    Okay, es müsste

    int found[3]
    

    heißen um 3 Einträge zu haben. Nämlich found[0], found[1] und found [2]. Ändert aber nix am Fehler

    Dann gib mal bitte ein vollständiges Beispiel an, siehe dritter Link in meiner Signatur.

    Ein weiterer Fehler ist zum Beispiel deine Einleselogik aus Prüfung, Lesen, Verarbeiten. Dadurch verarbeitest du im Fehlerfall (Dateiende) einen ungültigen Datensatz, da die Prüfung vor dem Lesefehler stattfindet.



  • Ok, ich versuchs nochmal 🙂

    Hier ist der Code:

    #include <iomanip>
    #include <iostream>
    #include <string>
    #include <vector>
    #include <fstream>
    using namespace std;
    
    class MA_LEG
    {	private: 
    		string mOrigin;
    		string mDestination;
    
    	public:
    		MA_LEG() {;}
    
    		const string getmOrigin() { return mOrigin; }
    		const string getmDestination() { return mDestination; }
    
    		string setmOrigin(string mOrigin) {this->mOrigin=mOrigin;}
    		string setmDestination(string mDestination) {this->mDestination=mDestination;}
    
    		static void ImportData(string file);
    };
    
    void MA_LEG::ImportData(string file)
    {
    ifstream read;
    read.open (file.c_str());
    string row;
    vector<MA_LEG> listoflegs;
    
    while(!read.eof())
    {
    	MA_LEG objekt;
    	getline(read,row);
    	int found[3];
    	found[0]=-1;
    
    		found[1]=row.find_first_of(';', found[1-1]+1);
    		objekt.setmOrigin(row.substr(found[1-1]+1,found[1]-found[1-1]-1));
    		cout << "|" << setw(1) << objekt.getmOrigin() << "|" ;
    
    		found[2]=row.find_first_of(';', found[2-1]+1);
    		objekt.setmDestination(row.substr(found[2-1]+1,found[2]-found[2-1]-1));
    		cout << setw(1) << objekt.getmDestination() << "|" << found[1] << found[2] << endl; 
    
    		listoflegs.push_back(objekt);
    }
    read.close();
    cout << listoflegs.size();
    }
    
    int main()
    {
    string file;
    cout << " Bitte geben Sie eine einzulesende Leg-Datei ein: " << endl;
    cout << " ";
    cin >> file;
    cout << endl;
    
    MA_LEG::ImportData(file);
    return 0;
     }
    

    Was will ich?

    Ich habe eine csv Datei mit Paaren von Strings (Städte in diesem Fall) die durch Semikolons getrennt sind
    Ich suche in found die Semikolons und trenne die strings dazwischen raus mit substr
    Diese strings speicher ich in objekten meiner Klasse ab über die set-Methode
    Jede Zeile soll ein objekt von MA_LEG sein, was ich dann in den Container listoflegs schiebe und fülle.
    Kompilierung funktioniert
    Das Ganze geht die ersten fünf Zeilen supergut, aber dann ist es vorbei mit diesem STATUS_ACCESS_VIOLATION Fehler.
    Außerdem kommt eine .exe.core Datei dazu, die mir das was ich oben schonmal gepostet habe ausspuckt

    @SeppJ: Das mit der fehlerhaften Einleselogik seh ich in meinem Code irgendwie nicht


  • Mod

    Mathias1986 schrieb:

    @SeppJ: Das mit der fehlerhaften Einleselogik seh ich in meinem Code irgendwie nicht

    Nur ganz schnell, ohne mir den Rest anzusehen:

    while (!read.eof()) // hier prüfst du, ob der Stream eof gesetzt hat. (Warum eigentlich nur eof und nicht auch alle anderen Fehler?)
    {
     // ...
     getline(read,row); // Hier liest du etwas aus dem Stream, dabei kann eof erreicht werden und das Lesen dadurch scheitern
     // ...
     // Hier verarbeitest du row, egal was beim getline passiert ist, der Lesefehler wird erst beim nächsten Durchlauf entdeckt.
     // Zuvor wird dann irgendeine Nonsenszeile verarbeitet
    }
    

    Von der Logik richtig wäre:

    while (getline(read, row))
    {
     // Hier Verarbeitung von row
    }
    

    Das ist ein ganz typisches Antipattern von Leuten, die früher C gemacht haben und nun versuchen, C mit Klassen zu machen. Der Rest deiner Dateibehandlung sieht ähnlich aus (open, close). Darf ich fragen, was dein Lehrbuch ist? Es macht keinen guten Eindruck.



  • Dirk Louis - From Zero to Hero C++



  • Mathias1986 schrieb:

    From Zero to Hero C++

    Und so ein reißerischer Titel lässt dich nicht stutzen? 😉 Normalerweise sind solche Titel, die einem große Versprechen machen (von A bis Z, in 21 Tagen, ...) das Papier nicht wert, auf dem sie gedruckt sind. Bei Dirk Louis bekommt man leider auch hin und wieder den entsprechenden Eindruck - ich hab daheim eine C/C++ Referenz von ihm, die einem zwar einen groben Überblick gibts, die man aber nicht zu wörtlich nehmen darf, weil da leider auch oft Mist rauskommt.



  • Gut zu wissen. Ich mein als Einstieg wars jetzt schon nicht schlecht,
    aber solche Details ob das jetzt gut oder schlecht ist kann ich natürlich nicht rauslesen.

    Weiß jemand warum mein Programm fehlerhaft ist? 😃



  • SeppJ schrieb:

    Das ist ein ganz typisches Antipattern von Leuten, die früher C gemacht haben und nun versuchen, C mit Klassen zu machen.

    So ein Blödsinn.


  • Mod

    Bashar schrieb:

    SeppJ schrieb:

    Das ist ein ganz typisches Antipattern von Leuten, die früher C gemacht haben und nun versuchen, C mit Klassen zu machen.

    So ein Blödsinn.

    Stimmt. Ich bin zu eingerostet in C. Korrigiere:

    Das ist ein ganz typisches Antipattern von Leuten, die früher C Pascal gemacht haben. Es taucht auch sehr oft in schlechten C (und C++) Büchern auf und ist dadurch ein deutliches Warnsignal, dass dieses Buch nicht zu benutzen ist.



  • Problem offenbar gelöst!!!

    Ich hatte bei den set-Funktion die Ausgabeformate string. Das ist natürlich quatsch, ich schreibe dort void hin und alles funktioniert. Kann jetzt im Nachhinein jemand erklären warum das so war mit dem Laufzeitfehler? Ist doch irgendwie kurios oder? Wieso hatte das so eine seltsame Auswirkung?

    Jetzt kann ich beruhigt schlafen 😉 und den Dirk Louis leg ich dann wohl doch mal beiseite.

    Bis dann und thx für die schnellen Antworten!!!


  • Mod

    Über das Ende einer Funktion mit Rückgabewert zu laufen, ohne etwas zurück zu geben, erzeugt undefiniertes Verhalten.

    Konkret wird hier wohl versucht werden, eine Kopie von einem String zu erzeugen, der gar nicht da ist. Da ein String ein komplexes Objekt ist, wegen der fehlenden Rückgabe aber bloß irgendwelcher Datenmüll da steht, scheitert dies grandios.



  • SeppJ schrieb:

    Das ist ein ganz typisches Antipattern von Leuten (...)

    Das ist ein ganz typisches Antipattern von Leuten, die iostreams über eine Referenz-Doku gelernt haben (oder mit Hilfe von Manuskripten/Büchern die von Leuten verfasst wurden, die die iostreams über eine Referenz-Doku gelernt haben etcpp.).

    Dass ein Stream implizit nach bool konvertierbar ist, ist zwar sehr praktisch, aber auch vollkommen unintuitiv.


Anmelden zum Antworten