zeitweise Abschmierende Funktion



  • Hi mal wieder...

    Ich habe einen konsolenbasierten Editor für nen Textadventure.

    Hier gibt es die Klasse cObj zur Objektverwaltung.

    Unter Anderem kann man Objekte speichern. Die Methode hierzu sieht so aus :

    void cObj::Save (void)
    { /* Sichere ini-Datei */
       FILE *Fi;
    
       Fi = fopen (FileName, "wb");
    
       if ( Fi != NULL) /* wenn Datei schreibbar */
       {   /* Datei schreiben */
             fwrite ( &cntData , sizeof (unsigned long), 1      , Fi);
             fwrite ( Data     , Objsize               , cntData, Fi);
           fclose (Fi);
       }
    }
    

    an sich ist das ja ganz simpel..

    baue ich nun ein Testkonstrukt ungefähr so :

    int main(int argc, char *argv[])
    {
      cObj *Obj = new cObj("object");
    
      Obj->Save();
    
      delete Obj;
    
      return 0;
    }
    

    klappt das ganze..

    aaber in meinem Programm welches aus ner schleife - ähnlich dem Windows-Loop besteht, schmiert es mir beim fopen() ab.

    Kann mir wer erklären, was das Ganze soll?

    Wenn es gewünscht ist, lade ich mal das komplette Ding hoch..
    ist zwar nicht besonders schön, aber es sollen kleine tools sein, da bin ich immer etwas - unsauber..



  • DocJunioR schrieb:

    aaber in meinem Programm welches aus ner schleife - ähnlich dem Windows-Loop besteht, schmiert es mir beim fopen() ab.

    du meinst direkt die fopen()-funktion stürzt ab?
    was ist mit 'Filename'?
    zeigt der auch wirklich _immer_ auf einen string?



  • der Constructor der Klasse hat einen Parameter Name (habe keine überladenen Contructors) und aus diesem wird der FileName per sprintf erstellt.. das funktioniert ja auch..



  • DocJunioR schrieb:

    der Constructor der Klasse hat einen Parameter Name (habe keine überladenen Contructors) und aus diesem wird der FileName per sprintf erstellt.. das funktioniert ja auch..

    na da kann aber schon einiges schiefgehen. lass es am besten mal im debugger laufen. wenn's stehenbleibt dann guck' dir die parameter von fopen() an.



  • Der DevCpp - Debugger kommt mit Klassen net klar 😞



  • DocJunioR schrieb:

    Der DevCpp - Debugger kommt mit Klassen net klar 😞

    Lad das Ganze doch mal hoch, ich wuerds mir mal anschauen.

    mfg
    v R



  • okay :

    http://mitglied.lycos.de/jrapp/objcon.html

    viel glück..
    hab nur wenig kommentiert *asche auf mein haupt*



  • DocJunioR schrieb:

    okay :

    http://mitglied.lycos.de/jrapp/objcon.html

    viel glück..
    hab nur wenig kommentiert *asche auf mein haupt*

    Da ist noch viel zu tun, damit das rund läuft. Ich hab das mal mit Valgrind gestartet. Einer von vielen Fehlern war zum Beispiel:

    ==12870== Conditional jump or move depends on uninitialised value(s)
    ==12870==    at 0x42028D59: bsearch (in /lib/tls/libc-2.3.2.so)
    ==12870==    by 0x8048CB1: cObj::GetPos(sObject*, int) (cObj.cpp:41)
    ==12870==    by 0x8048F6E: cObj::Get(sObject*, int) (cObj.cpp:125)
    ==12870==    by 0x8049319: cObjCreator::SetMenu() (cobjcreator.cpp:19)
    ==12870==    by 0x80498F9: cObjCreator::Start() (cobjcreator.cpp:88)
    ==12870==    by 0x804AFA0: main (main.cpp:9)
    

    Dies geschieht, wenn man als erstes nach einer nicht vorhandenen ID sucht.

    Dann würde ich mir mal die Reihenfolge in diesem Konstruktor mal genauer anschauen angesichts der Initialisierung der Elemente.

    cFramebuf::cFramebuf (void)
    {
        Clear();
        RetWin();
        Show();
    }
    

    Und hier ist auch etwas nicht gerade glücklich gewählt:

    typedef char tFBuffer[80*24];
    


  • wenn man nach einer nicht vorhandenn ID sucht, sucht der bsearch ne leere Liste durch.. Man könnte maximal überprüfen, ob überhaupt nen Element in der Liste ist. Aber es ist kein Fehler, der das Programm zum Abschmieren bringt, insofern kümmere ich mich ein anderes Mal darum..

    okay, das Clear sollte nach dem RetWin kommen.. ändere ich sofort..

    Den Framebuffer hab ich absichtlich eine Zeile zu kurz gemacht, weil mir sonst nen Bildvorschub die erste Zeile klaut. Ginge auch anders, aber ich möchte keine Interrupts nutzen und eine C-Funktion hierfür gibts nicht (die conio vom mingw ist nichtmal zur Hälfte implementiert..)



  • DocJunioR schrieb:

    Den Framebuffer hab ich absichtlich eine Zeile zu kurz gemacht, weil mir sonst nen Bildvorschub die erste Zeile klaut. Ginge auch anders, aber ich möchte keine Interrupts nutzen und eine C-Funktion hierfür gibts nicht (die conio vom mingw ist nichtmal zur Hälfte implementiert..)

    Dafür schreibt zum Beispiel die Clear() Funktion dann in die fehlende Zeile hinein und überschreibt Speicher, der zum Absturz führen kann.



  • Andere Fehler sind:

    ==13203== Conditional jump or move depends on uninitialised value(s)
    ==13203==    at 0x3C01DE12: strcmp (mac_replace_strmem.c:252)
    ==13203==    by 0x8048C1D: cmpName(void const*, void const*) (cObj.cpp:28)
    ==13203==    by 0x4202936F: msort_with_tmp (in /lib/tls/libc-2.3.2.so)
    ==13203==    by 0x4202959F: qsort (in /lib/tls/libc-2.3.2.so)
    ==13203==    by 0x80490FA: cObj::Put(sObject*, int) (cObj.cpp:166)
    ==13203==    by 0x804A0F0: cObjCreator::Start() (cobjcreator.cpp:202)
    ==13203==    by 0x804AFA0: main (main.cpp:9)
    
    ==13203== Invalid read of size 4
    ==13203==    at 0x8048BEC: cmpObj(void const*, void const*) (cObj.cpp:20)
    ==13203==    by 0x4202959F: qsort (in /lib/tls/libc-2.3.2.so)
    ==13203==    by 0x8049122: cObj::Put(sObject*, int) (cObj.cpp:167)
    ==13203==    by 0x804A0F0: cObjCreator::Start() (cobjcreator.cpp:202)
    ==13203==    by 0x804AFA0: main (main.cpp:9)
    ==13203==  Address 0x3C19627C is not stack'd, malloc'd or free'd
    
    ==13203== Invalid read of size 4
    ==13203==    at 0x8048BEC: cmpObj(void const*, void const*) (cObj.cpp:20)
    ==13203==    by 0x8048CB1: cObj::GetPos(sObject*, int) (cObj.cpp:41)
    ==13203==    by 0x8048F6E: cObj::Get(sObject*, int) (cObj.cpp:125)
    ==13203==    by 0x8049319: cObjCreator::SetMenu() (cobjcreator.cpp:19)
    ==13203==    by 0x80498F9: cObjCreator::Start() (cobjcreator.cpp:88)
    ==13203==    by 0x804AFA0: main (main.cpp:9)
    ==13203==  Address 0x3C19627C is not stack'd, malloc'd or free'd
    

    Es wurden dabei zwei Einträge erzeugt und dann die Liste gespeichert.



  • Wow DocJuniors Code ist echt aus der alleruntersten Schublade.

    C mit Klassen oder so. 👎



  • ads schrieb:

    Wow DocJuniors Code ist echt aus der alleruntersten Schublade.

    C mit Klassen oder so. 👎

    Sehr konstruktiver Beitrag, haettest du dir sparen koennen!

    Das MinGW-Developer-Studio bringt im Debugger folgenden segfault:

    Program has received a signal-name="SIGSEGV",signal-meaning="Segmentation fault" at cObj::Put(sObject*, int)({name="this",value="0x3d2720"},{name="data",value="0x3d24cc"},{name="Mask",value="2"}), file C:\daten\source\cpp\objcon\cObj.cpp:157
    Program has received a signal-name="SIGSEGV",signal-meaning="Segmentation fault" at cObj::Put(sObject*, int)({name="this",value="0x3d2720"},{name="data",value="0x3d24cc"},{name="Mask",value="2"}), file C:\daten\source\cpp\objcon\cObj.cpp:157

    Es ist fuer mich schwer es zu reproduzieren. Ich habe mehrmals nach einer nicht-
    existenten ID gesucht (obwohl ich sie nach dem ersten Mal eigentlich gespeichert
    hatte). Irgendwann ist er dann in der Memberfunktion 'Put' mit einem Segfault
    raus.

    mfg
    v R



  • oookay, ich fang dann erstmal an und baue die Sache mit dem bsearch um..
    dann sollten diese Fehler erstmal raus sein.. warum er abschmiert ist mir auch nicht klar.

    zum AufmerksamkeitsDefizitSyndrom : Ich bin eigentlich C-Programmierer. Zeitweise nutze ich aber das Klassenkonzept, wenn es mir sinnvoll erscheint.. Kann übrigens jeder nachlesen. Ich schreib das immer wieder.

    Weiterhin ist das Rumtrollen schon seit ca. 1/2 Jahr out. Wenn du was zu meinem Stil zu sagen hast zeig wenigstens, dass du Arsch in der Hose hast und tu's registriert...



  • Soo, hab grade mal nach ner Woche wieder rein gesehen...
    @ Ponto.. dein Kommentar war die Lösung..

    bei RetWin setze ich das Fenster auf ne Größe von 80*25 Zeichen. da mein Speicher aber nur 80*24 ist, werden beim clear 80 Zeichen zu viel beschrieben..
    Da muss wohl auch mein Filedescriptor gelegen haben...


Anmelden zum Antworten