Programmfehler durch Funktion



  • Hallo zusammen,

    ich habe eine Funktion die aus einer binärDatei, einen Vektor einer Klasse mit Objekten füllt. Dies ist eine Funktion zum laden zuvor gespeicherter Daten. Rufe ich diese Funktion auf, funktioniert zunächst alles wie gewünscht. Allerdings erzeugt das Programm beim schließen einen Fehler und schmiert gelegentlich auch zur Laufzeit ab. Wird diese Funktion nicht aufgerufen funktioniert alles einwandfrei.

    Habe ich in der Funktion vielleicht einen offensichtlichen Fehler? Ich selbst weiß gerade nicht wo ich weiter suchen kann und bin auch recht neu in der Materie. Deswegen bin ich wirklich dankbar für jeden Hinweis.

    Die besagte Funktion:

    vector<tFinger> LoadFile(string imgpath)
    {
        imgpath="data/"+imgpath;
        cstr = new char [imgpath.size()+1];  
        strcpy (cstr, imgpath.c_str());
    
        ladeFinger.clear();
        ifstream ifs(cstr, ios::binary); 
    
        if (ifs.is_open())
        {
            while (!ifs.eof())
            {
                ifs.read((char *)&lFinger, sizeof(tFinger));   
                ladeFinger.push_back(tFinger());
                ladeFinger.back()=lFinger;                  
            }
            ifs.close();
        }
        return ladeFinger;
    }
    

    Vielen Dank für die Mühe,
    Atme



  • Was soll denn das Gebastel mit dem char-Array darstellen (das du übrigens nirgens freigibst)? Das ist unnötig - du kannst auch imgpath.c_str() direkt an den Stream-Konstruktor übergeben.

    Zweitens liefert eof() erst dann true zurück, wenn die vorige Lese-Operation schiefgegangen ist, d.h. im letzten Schleifendurchlauf hast du ein ungültiges Objekt.

    PS: Wie ist eigentlich die Klasse tFinger definiert? Damit könntest du auch Probleme haben.



  • Wozu wird erst ein tFinger() per push_back eingefügt, um den Wert dann gleich wieder zu überschreiben? Du kannst doch gleich den richtigen Wert einfügen.



  • Ich glaube ich habe selten so eine hässliche Pfuscherei gesehen. Mich wunderts nicht, dass das abstürzt.



  • Hi,

    danke für die Antworten. Pfuscherei, ja klar. Ich probiere und lerne.

    Ich erhoffe mir auch nicht die Patentlösung, aber vielleicht habe ich einen Fehler verursacht der in dem Code offensichtlich zu besagtem Fehlverhalten führt und schnell ersichtlich ist. Ansonsten bleibt mir nichts übrig, als alles nocheinmal aufzuräumen und weiter zu grübeln.

    Das mit dem push_back habe ich bereits geändert, macht natürlich keinen Sinn.

    Das ungültige Objekt habe ich durch eine weitere Abfrage abgefangen, verursacht aber auch nicht den Fehler. Der merkwürdigerweise erst beim Beenden auftritt und nur wenn die besagte Funktion aktiv wird. Es muss ein Speicherproblem sein?!

    Hier die Klasse tFinger. Dazu sei noch erwähnt, dass ich mich dem Openframeworks bediene, welches mit GLUT wirkt.

    So long,

    Atme

    class tFinger 	
    {
    public:		
    
    tFinger()
        {
        touch=false;id=-1; x=-1; y=-1;dauer=0;
        }	
    
    float GetTime(float zeit){return zeit-dauer;}
    float SetTime(float zeit){dauer=zeit;}
    
        bool touch;
        float dauer;
        int id;
        int x;
        int y;
        int menu;
    
        ofxVec3f pktA;
        ofxVec3f pktB;
        ofxVec3f Bewegung;
        bool pktAset;
    
        ofxVec3f	pts[1500]; 
        int		nPts;
    }
    


  • Atme schrieb:

    ifs.read((char *)&lFinger, sizeof(tFinger));
    

    und

    Atme schrieb:

    class tFinger     
    {
    public:        
    
    tFinger()
        {
        touch=false;id=-1; x=-1; y=-1;dauer=0;
        }    
    
    float GetTime(float zeit){return zeit-dauer;}
    float SetTime(float zeit){dauer=zeit;}
    
        bool touch;
        float dauer;
        int id;
        int x;
        int y;
        int menu;
    
        ofxVec3f pktA;
        ofxVec3f pktB;
        ofxVec3f Bewegung;
        bool pktAset;
    
        ofxVec3f    pts[1500]; 
        int        nPts;
    }
    

    sehen schon mal gefährlich aus, da tFinger aufgrund der member ofxVec3F möglicherweise kein POD (Plain old data, für google) ist, den man blockweise einlesen kann.
    Mach´s wie in C++ vorgesehen: überlade die Stream Operatoren, um tFinger Objekte zu lesen und zu schreiben.



  • Atme schrieb:

    // ...
            while (!ifs.eof())
            {
                ifs.read((char *)&lFinger, sizeof(tFinger));
    

    Hallo Atme,

    diese Konstruktion liest ein tFinger-Objekt zuviel ein. Der Inhalt sollte jedoch mit dem letzten in der Datei übereinstimmen. Zu der while(!EOF)-read-Schleife siehe auch hier.

    Besser ist:

    for( tFinger f; ifs.read((char *)&f, sizeof(tFinger)); ) {
            ladeFinger.push_back( f);
        }
        if( !ifs.eof() || ifs.gcount() != 0 ) // oder ifs.gcount() != sizeof(tFinger); muss ich morgen nochmal nachsehen
            cerr << "Lesefehler" << endl;
    

    ansonsten gilt das bereits gesagte; prüfe bitte, ob ofxVec3f ein POD ist.

    Gruß
    Werner


Anmelden zum Antworten