Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 19

Thema: SIGTRAP /SIGSEGV malloc etc..

  1. #1
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    SIGTRAP /SIGSEGV malloc etc..

    Hi,

    da ich den Studiengang gewechselt habe, studiere ich jetzt Informatik; was den Grund dafür darstellt, dass ich mich mit so Steinzeitsprachen wie C auseinandersetzen muss.
    Habe ich doch in der Vergangenheit immer einen grossen Bogen um dynamische Speicherverwaltung machen können, da fehleranfällig und unnötig für nicht zeitkritische Anwendungen, jetzt muss ich leider ein paar recht umfangreiche Übungsaufgaben zu dem Thema fertigstellen:
    http://public.beuth-hochschule.de/~kempfer/
    (links SS2011, Übungsaufgabe 1-5)

    Ich hänge seit gestern bei Aufgabe 4 fest (Abgabetermin ist morgen ^^). Im Prinzip geht es dabei um einen simplifizierten XML-Parser. Nebenbei sei erwähnt, dass jegliche Strings per malloc reserviert werden sollen. Aufgabe 4 war soweit fertiggestellt worden, da bekam ich völlig unerwartet einen SIGSEGV/ SIGTRAP..
    Konnte erstmal gar nichts damit anfangen, google sagte, das wäre korrupte Heap Memory, also ich greife auf Speicher zu, der mir nicht gehört.
    Also erstmal alle Arraygrenzen gecheckt, Fehler verbessert.
    Dann malloc Aufrufe durchgegangen, sizof wurde falsch berechnet, verbessert.
    free()s wegkommentiert, nur um zu sehen, ob möglicherweise falscher speicher freigegeben werden sollte.
    Half alles nichts, also habe ich zeilenweises chronologisches oldschool-auskommentieren mit trial&error vollzogen. Allerdings war ich mir nicht sicher, ob nur deswegen, weil der Fehler ausbleibt, auch kein Fehler mehr vorhanden ist; hatte ich doch gelesen, dass corrupted heap mem nur in Folge Fehler auslöst. Bin dann zu dem Punkt gelangt wo kein Fehler mehr auftrat und konnte eingrenzen, welche Funktionen möglicherweise betroffen waren:
    Code:
    //Beseitigt Leerzeichen am Anfang und Ende eines Strings
    char* trim(char* uncleaned)
    {
        int length = strlen(uncleaned);
        char buf[length + 1]; // + 1 für terminator \0
        int i;
        int start = 0;
        int end = 0;
        int n = 0;
    
        //Position d. ersten Nichtleerzeichens ermitteln
        for (i=0; i<=(length - 1); i++)
        {
            if (uncleaned[i] != ' ')
            {
               start = i;
               break;
            }
        }
    
         //Position d. letzten Nichtleerzeichens ermitteln
        for (i=(length - 2); i>=0; i--)  //-2, um nicht den Terminator \0 einzubeziehen
        {
            if (uncleaned[i] != ' ')
            {
               end = i;
               break;
            }
        }
    
        //String von start bis ende kopieren
        for (i=0; i<=(length - 1); i++)
        {
            if ((i >= start) && (i <= end))
                buf[n++] = uncleaned[i];
        }
    
        buf[n] = '\0'; //String Terminator
        char* cleaned = malloc(sizeof(char) * strlen(buf));
        if (NULL == cleaned) //zu wenig Speicher
            die("tools.c -> trim: Zu wenig Arbeitsspeicher");
        strcpy(cleaned, buf);
        return(cleaned);
    }
    
    
    //Reserviert dynamisch Speicher für einen String, kopiert diesen hinein und gibt eine Referenz darauf zurück
    char* allocateString(char* data)
    {
        char* newstr = malloc(sizeof(char) *strlen(data));
        if (NULL == newstr) //zu wenig Speicher
                die("tools.c -> allocateString: Zu wenig Arbeitsspeicher");
        strcpy(newstr, data);
        return(newstr);
    }
    Für Hinweise, was falsch laufen könnte wäre ich sehr dankbar.
    Ich lade gerne den vollständigen Code hoch, wenn gewünscht.

    Gruss

    GF
    Signatur sowie alle persönlichen Informationen entfernt.

  2. #2
    Moderator
    Nothing is unbreakable!

    Registriert seit
    Jul 2003
    Beiträge
    622
    Renommee
    819

    Re: SIGTRAP /SIGSEGV malloc etc..

    Hai,
    ich werd es mir mal anschauen heute. valgrind ist da ein sehr hilfreiches Tool.

  3. #3
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    Re: SIGTRAP /SIGSEGV malloc etc..

    Zitat Zitat von retak Beitrag anzeigen
    Hai,
    ich werd es mir mal anschauen heute. valgrind ist da ein sehr hilfreiches Tool.
    Danke ;)
    Leider scheint es valgrind nur für Linux zu geben, ich bin aber gezwungen Win 7 zu nutzen über einen NX Client, welcher Linux tunnelt. IDE ist Code::Blocks.
    Signatur sowie alle persönlichen Informationen entfernt.

  4. #4
    Moderator
    Nothing is unbreakable!

    Registriert seit
    Jul 2003
    Beiträge
    622
    Renommee
    819

    Re: SIGTRAP /SIGSEGV malloc etc..

    Nun, C compiliert auch unter Linux.

    So, dann fängen wir mal an ;)
    The strlen() function calculates the length of the string s, not including the terminating '\0' character.
    The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0')
    Zeile 53 ändert sich wie folgt
    Code:
    char* newstr = malloc(sizeof(char) *strlen(data));
    nach
    Code:
    char* newstr = (char*) malloc(strlen(data) + 1);
    Bessere ist es strncpy() zu nutzen und anzugeben, wieviel Byte kopiert werden soll. Wenn das Nullbyte am Ende mal fehlt, kopiert strcpy munter weiter. Zeile 44,45 nochmal.

    Zeile 10
    Code:
    char buf[length + 1]; // + 1 für terminator \0
    Gut, an das +1 gedacht. Aber diese Variable landet auf dem Stack. Der ist aber auf ein paar MB begrenzt. Natürlich wird dein String jetzt nicht eine Millionen Zeichen lang sein, aber dennoch. Valgrind würde so einen starken Zuwachs im Stack auch anzeigen. Noch dazu ist diese Variable garnicht nötig, wie ich gleich zeigen werde.

    Zeile 17
    Code:
    for (i=0; i<=(length - 1); i++)
    Ja. Nein. So ists schöner
    Code:
    for (i=0; i < length; i++)
    Zeile 26
    Code:
     for (i=(length - 2); i>=0; i--)  //-2, um nicht den Terminator \0 einzubeziehen
    strlen() rechnet das Nullbyte nicht mit ein. Ein -1 wäre richtig. Sonst wird ein abschliessendes \n auch noch entfernt.

    Zeile 36-45
    Code:
        //String von start bis ende kopieren
        for (i=0; i<=(length - 1); i++)
        {
            if ((i >= start) && (i <= end))
                buf[n++] = uncleaned[i];
        }
    
        buf[n] = '\0'; //String Terminator
        char* cleaned = malloc(sizeof(char) * strlen(buf));
        strcpy(cleaned, buf);
    Wie gesagt kann man die buf Variable einsparen, indem du die Schleife gleich in cleaned schreiben lässt. cleaned ist dann end-start Zeichen lang? Das überlasse ich dir :)

    Speicherfehler hab ich und valgrind sonst nicht gefunden.

  5. #5
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    Re: SIGTRAP /SIGSEGV malloc etc..

    wow!
    Habe alles angepasst und der Fehler ist verschwunden! Göttlich! Du ahnst nicht,
    wieviele Stunden ich verzweifelt gesucht habe xD

    Folgendermassen wurde das Problem gelöst:
    Code:
    //Beseitigt Leerzeichen am Anfang und Ende eines Strings
    char* trim(char* uncleaned)
    {
        int length = strlen(uncleaned);
        if (length == 0)
        {
            char* str = allocateString("");
            return str;
        }
        int i;
        int start = -1;
        int end = -1;
        int n = 0;
    
        //Position d. ersten Nichtleerzeichens ermitteln
        for (i=0; i<=(length - 1); i++) //
        {
            if (uncleaned[i] != ' ')
            {
               start = i;
               break;
            }
        }
    
         //Position d. letzten Nichtleerzeichens ermitteln
        for (i=(length - 1); i>=0; i--)  //-1, um nicht den Terminator \0 einzubeziehen
        {
            if (uncleaned[i] != ' ')
            {
               end = i;
               break;
            }
        }
    
        char* newstr = (char*) malloc(end - start + 2); // + 1 wg. [0]-start + 1 wg. string terminator \0
    
        //String von start bis ende kopieren
        for (i=start; i<=end; i++)
            newstr[n++] = uncleaned[i];
        newstr[n] = '\0'; //String Terminator
    
        if (NULL == newstr) //zu wenig Speicher
            die("tools.c -> trim: Zu wenig Arbeitsspeicher");
        return(newstr);
    }
    
    
    //Reserviert dynamisch Speicher für einen String, kopiert diesen hinein und gibt eine Referenz darauf zurück
    char* allocateString(char* data)
    {
        char* newstr = (char*) malloc(strlen(data) + 1);
        if (NULL == newstr) //zu wenig Speicher
                die("tools.c -> allocateString: Zu wenig Arbeitsspeicher");
        strncpy(newstr, data, (strlen(data) + 1));
        return(newstr);
    }
    Ein anständiger Compiler findet sowas gleich oder gibt eine Warnung aus, nicht jedoch bei C. C stinkt. Oder vielleicht muss ich mich erst dran gewöhnen ;)
    Danke retak.

    [EDIT] achja, die Strings in diesem Programm sind auf 60 Zeichen begrenzt, weswegen der Stack locker ausreicht.
    Geändert von GoodFella (19.05.2011 um 20:57 Uhr)
    Signatur sowie alle persönlichen Informationen entfernt.

  6. #6
    Moderator
    Nothing is unbreakable!

    Registriert seit
    Jul 2003
    Beiträge
    622
    Renommee
    819

    Re: SIGTRAP /SIGSEGV malloc etc..

    Bitte :)
    Hehe, naja, da war nicht dabei was den Compiler stören sollte. Ist eben low Level. C, ist es zu stark, bist du zu schwach ;)
    Freut mich, das ich helfen konnte.

  7. #7
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    4.985
    Renommee
    903

    Re: SIGTRAP /SIGSEGV malloc etc..

    Ein anständiger Compiler findet sowas gleich oder gibt eine Warnung aus, nicht jedoch bei C. C stinkt.
    Und das von einem so qualifizierten Studenten, der es nichtmal schafft einen Schleife richtig aufzuschreiben. Und ich dachte mein Kollege uebertreibt als er von seinen unwissenden, lernfaulen und gleichzeitig aber arroganten Studenten sprach.

  8. #8
    Member
    Registriert seit
    May 2004
    Beiträge
    1.432
    Renommee
    1142

    Re: SIGTRAP /SIGSEGV malloc etc..

    Generation Java. :-B

  9. #9
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    Re: SIGTRAP /SIGSEGV malloc etc..

    @dumm: Du machst deinem Namen alle Ehre. Dann drück es doch direkt aus und sag: "GF, du bist unwissend, lernfaul und gleichzeitig arrogant."
    Seitwann geht unwissend als Beleidigung durch? :P
    Und lernfaul bin ich nur da, wo ich den Zweck als nicht effizient erachte.
    Deine Antwort jedoch ist extrem arrogant mir gegenüber.

    @shaka: Nö. Angefangen hab ich 1994 mit Pascal. Dann kam Delphi, Perl, Step7, LabView, Ada, C++, Java, VB, php und jetzt C.
    Nach wie vor ist Perl das Mittel meiner Wahl, wenn es um nicht-zeitkritische Aufgaben geht; deswegen auch meine Abneigung C gegenüber ^^
    Springt der shaka gleich auf den dumm-Zug auf haha ^^

    Ich habe die Aufgaben heute mit Erfolg abgegeben, danke nochmal retak ;)
    Signatur sowie alle persönlichen Informationen entfernt.

  10. #10
    Registered User
    Registriert seit
    Aug 2002
    Beiträge
    2.212
    Renommee
    622

    Re: SIGTRAP /SIGSEGV malloc etc..

    WTF, Ihr seid doch alle aggressiv, overkilled und schlecht angezogen; also was flamed Ihr hier rum.
    Wenn ich was sage, will das was heißen.

  11. #11
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    Re: SIGTRAP /SIGSEGV malloc etc..

    haha :D
    da sind wir bei dir doch in bester gesellschaft xD
    Signatur sowie alle persönlichen Informationen entfernt.

  12. #12
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    4.985
    Renommee
    903

    Re: SIGTRAP /SIGSEGV malloc etc..

    Und lernfaul bin ich nur da, wo ich den Zweck als nicht effizient erachte.
    Das ist genau das Problem. Manchmal muss man Dinge tun, dessen tieferen Sinn man erst spaeter erkennt.

  13. #13
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    Re: SIGTRAP /SIGSEGV malloc etc..

    nein.
    Signatur sowie alle persönlichen Informationen entfernt.

  14. #14
    Moderator
    Registriert seit
    Aug 2004
    Beiträge
    1.310
    Renommee
    1286

    Re: SIGTRAP /SIGSEGV malloc etc..

    Die Diskussion darüber was man lernen muss und was nicht, tut hier nichts zur Sache. Bitte bleibt sachlich und spart euch diese ad hominem Argumente.

  15. #15
    Registered User
    Registriert seit
    Aug 2000
    Beiträge
    1.077
    Renommee
    457

    Re: SIGTRAP /SIGSEGV malloc etc..

    OffTopic:

    Zitat Zitat von dumm'
    SIGTRAP /SIGSEGV malloc... 20.05.2011 20:01 dumm' Du bist fuer ein Studium nicht geeignet. Wetten Du brichst wieder ab?
    Sehr geehrter Herr *********,
    Sie haben in der Klausur 95 Punkte und damit eine 1,0 erreicht.

    .. soviel zu meinem erneuten Versagen, dumm'. und nochmals danke, retak.

    Signatur sowie alle persönlichen Informationen entfernt.

Aktive Benutzer

Aktive Benutzer

Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)

Ähnliche Themen

  1. malloc()
    Von nimrod im Forum C / C++
    Antworten: 5
    Letzter Beitrag: 04.01.2004, 23:25
  2. [Linux] malloc(): Segmentaition fault
    Von Agavenwurm im Forum C / C++
    Antworten: 15
    Letzter Beitrag: 06.07.2003, 18:52
  3. Calloc vs. Malloc
    Von Quantumseeker im Forum C / C++
    Antworten: 2
    Letzter Beitrag: 14.04.2003, 23:39
  4. [C] malloc-Zuweisung
    Von BLACKrat im Forum C / C++
    Antworten: 2
    Letzter Beitrag: 16.09.2002, 17:01
  5. malloc usw
    Von Rocket im Forum C / C++
    Antworten: 3
    Letzter Beitrag: 02.10.2000, 18:05

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •