[SOLVED] malloc/realloc SegFault



  • hallo,

    ich hab momentan ein Problem mit Segmentation Faults, sehe aber leider das problem nicht... ich hab ein Kommentar gemacht, wo der Fehler auftritt. ich würde eigentlich den String bei jedem beginn der funktion getIniSet() auf "" setzen, aber dann krieg ich auch ein SegFault... ich hab die Ausgabe so gekürzt, dass nur noch die (meiner Meinung nach) relevanten Teile drinnen sind.

    das Problem ist, so wie ich es sehe: chPtrKey wird in readSections allokiert. in der getIniSet erfolgt dann nur ein realloc. Das funktioniert auch 1 Durchgang lang. Beim 2. Durchgang (2. Zeile aus Datei) krieg ich das SegFault.
    der GNU Debugger meldet, dass strcat() den SegFault verursacht. Mit einigen Testausgaben hab ich jedoch festgestellt, dass der SegFault schon bei realloc passiert.

    void readSections(void) {
    
       char chBuffer[100];
       char* chPtrKey   = (char*)malloc(sizeof(char)*1);
       char* chPtrValue = (char*)malloc(sizeof(char)*1);
    
       while ( fgets(chBuffer, 100, fp) != NULL ) {
          getIniSet(chBuffer, chPtrKey, chPtrValue);
          printf("> key: [%s] value: [%s]\n", chPtrKey, chPtrValue);
       }
    }
    
    void getIniSet(char* chPtrLine, char* chPtrKey, char* chPtrValue) {
       int i, iValueSection=0;
    
       char* chPtrCurrChr = (char*)malloc(sizeof(char)*2);
       chPtrKey   = (char*)realloc(chPtrKey, sizeof(char)*2);
       chPtrValue = (char*)realloc(chPtrValue, sizeof(char)*2);
    
       for ( i=0; i<strlen(chPtrLine); i++ ) {
          if ( chPtrLine[i] == '=' ) {
             iValueSection=1;
          }
          /* key section */
          if ( (chPtrLine[i]!=' ') && (iValueSection==0) ) {
             chPtrKey = (char*)realloc(chPtrKey, sizeof(char)*(strlen(chPtrKey)+2)); /* HIER tritt der fehler auf */
             strncpy(chPtrCurrChr, &chPtrLine[i], 1);
             strcat(chPtrKey, chPtrCurrChr);
          } else {
          /* value section */
             if ( !((strlen(chPtrValue)==0) && (chPtrLine[i]==' ')) ) {
                if ( (chPtrLine[i] != '=') && (chPtrLine[i] != '\n') ) {
                   chPtrValue = (char*)realloc(chPtrValue, sizeof(char)*(strlen(chPtrValue)+2));
                   strncpy(chPtrCurrChr, &chPtrLine[i], 1);
                   strcat(chPtrValue, chPtrCurrChr);
                }
             }
          }
       }
    }
    

    danke für eure hilfe!



  • Ist dir klar, dass Änderungen an den Werten der Zeiger chPtrLine, chPtrKey und chPtrValue sich nicht auf die beim Funktionsaufruf benutzten Parameter übertragen, weil beim Aufruf eine Kopie der Zeiger angelegt wird?

    Damit das funktioniert, musst du Zeiger auf Zeiger verwenden.



  • hi!

    danke für die aussage. irgendwie hab ich mir sowas schon gedacht.
    hab das ganze mal umgebaut. aber einen SegFault krieg ich immer noch 😞 und zwar an einer anderen stelle. es ist eigentlich die exakte kopie der "key" sektion... hab ich durch div. testausgaben rausgefunden...

    void readSections(void) {
    
       char chBuffer[100];
       char* chPtrKey   = (char*)malloc(sizeof(char)*2);
       char* chPtrValue = (char*)malloc(sizeof(char)*2);
    
       while ( fgets(chBuffer, 100, fp) != NULL ) {
          getIniSet(chBuffer, &chPtrKey, &chPtrValue);
          printf("> key: [%s] value: [%s]\n", chPtrKey, chPtrValue);
       }
    }
    
    void getIniSet(char* chPtrLine, char** chPtrKey, char** chPtrValue) {
       int i, iValueSection=0;
    
       char* chPtrCurrChr = (char*)malloc(sizeof(char)*2);
       *chPtrKey   = (char*)realloc(*chPtrKey, sizeof(char)*2);
       *chPtrValue = (char*)realloc(*chPtrValue, sizeof(char)*2);
    
       for ( i=0; i<strlen(chPtrLine); i++ ) {
          if ( chPtrLine[i] == '=' ) {
             iValueSection=1;
          }
    
          /* key section */
          if ( (chPtrLine[i]!=' ') && (iValueSection==0) ) {
             *chPtrKey = (char*)realloc(*chPtrKey, sizeof(char)*(strlen(*chPtrKey)+2));
             strncpy(chPtrCurrChr, &chPtrLine[i], 1);
             strcat(*chPtrKey, chPtrCurrChr);
          } else {
          /* value section */
             if ( !((strlen(*chPtrValue)==0) && (chPtrLine[i]==' ')) ) {
                if ( (chPtrLine[i] != '=') && (chPtrLine[i] != '\n') ) {
                   *chPtrValue = (char*)realloc(*chPtrValue, sizeof(char)*(strlen(*chPtrValue)+2)); /* FEHLER ist hier */
                   strncpy(chPtrCurrChr, &chPtrLine[i], 1);
                   strcat(*chPtrValue, chPtrCurrChr);
                }
             }
          }
       }
       free(chPtrCurrChr);
    }
    

    wahrscheinlich ist auch das der grund, warum
    *chPtrKey = ""; ein segfault auslöst oder?

    danke again!

    ciao



  • Ist dir klar, was strlen macht? Falls du glaubst, es gibt dir die bei malloc/realloc angegebene Größe zurück, liegst du falsch.

    Warum benutzt du für chPtrCurrChr überhaupt malloc?



  • MFK schrieb:

    Ist dir klar, was strlen macht? Falls du glaubst, es gibt dir die bei malloc/realloc angegebene Größe zurück, liegst du falsch.

    ja, das weiß ich - aber damit rechne ich ja auch nicht... er soll ja nur neuen speicher für das aktuelle wort +2 (1 neues zeichen und 1x \0) reservieren.

    Warum benutzt du für chPtrCurrChr überhaupt malloc?

    ja, aber das löst ja das segFault nicht aus. Hat es nachteile malloc zu verwenden - soll ich ein char[] verwenden?

    thx,
    ciao



  • so - ich habs jetzt "gelöst" - jedenfalls krieg ich kein SegFault mehr.

    *chPtrKey = NULL; STATT = "" hat geholfen.
    kann mir das wer erklären?

    thx



  • hephaistos6 schrieb:

    Hat es nachteile malloc zu verwenden - soll ich ein char[] verwenden?

    Dynamisch Speicher anfordern sollte man nur, wenn es nicht anders geht. Es dauert länger und kann fehlschlagen.

    hephaistos6 schrieb:

    *chPtrKey = NULL; STATT = "" hat geholfen.
    kann mir das wer erklären?

    *chrPtrKey = "";

    weist dem Zeiger die Adresse des Zeichenkettenliterals "" zu. Das liegt vermutlich irgendwo in einem Nur-Lese-Speicher, jedenfalls nicht in einem Bereich, der mit malloc angefordert wurde. Wenn man darauf realloc anwendet, knallt's.



  • thx 🙂 jetzt check ichs


Anmelden zum Antworten