core dump realloc



  • Hallo!

    Folgender Code führt zu einem Core dump:

    #include <assert.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
    
    char* help;
    //ich reserviere mir mit malloc mal speicher für die ersten zeichen(die abschließende \0 ist berücksichtigt).
    help = (char*) calloc(2,sizeof(char));
    if(help == NULL)
    {
     return -1;
    }
    int i = 0;
    unsigned char  *tok;
    //Nun gehe ich zeichen für Zeichen tok durch, also als ersters würde ich ein d //erhalten. 
    for(tok ="dasdsadasdasdsdasddsadasda"; *tok != '\0'; tok++)
    {
    
      // für jedes zeichen hole ich mir Speicher
      help = (char*) realloc(help, 1);
      if(help == NULL)
      {
        return -1;
      }
      // ich speichere an der Stelle i von help das gerade behandelte zeichen. Also // würde d an stelle 0 stehen a an der stelle 1(nächster durchlauf usw.
      *(help+i) = (int)*tok;
    
      i++;
    
    }
    help[i-1] = (int)'\0';
    
    return 0;
    }
    

    Es wird wohl an der Zeile *(help+i) = (int)*tok; liegen, aber wie würde diese Zeile korrekt lauten, wenn ich an der Stelle i in help das zeichen tok hinzufügen möchte?

    danke und lg



  • Kommentier mal deinen Code mit Beschreibungen, was du glaubst zu tun ...



  • Ein dynamisch reserviertes Array lässt sich genauso verwenden wie ein Statisches. (Bis auf free)
    Bei char tok[20]; ist tok ein Zeiger.
    Ein Zeiger muss initialisiert werden bevor er verwendet werden kann und zwar mit einer Speicheradresse.
    Und "dasdsadasdasdsdasddsadasda" ist keine Speicheradresse.
    Edit: Du musst nicht casten, calloc und realloc geben einen void Zeiger zurück, der auf alles zeigen kann. Eine einfache Zuweisung reicht aus.



  • hab jetzt auskommentiert.

    @Asyl-Dämon okay, des hilft mir jetzt nicht so wirklich, wie könnte ich das gewollte erreichen? 🙂



  • const char buffer[] ="dasdsadasdasdsdasddsadasda";
    unsigned char *tok;
    for(tok=&buffer;tok!='\0';tok++)
    {
    

    Das & ist zuständig für die Speicheradresse.
    Und zu den Casts:
    statt help = (char*) calloc(2,sizeof(char));
    kannst du auch einfach:
    help = calloc(2,sizeof(char));
    schreiben.



  • Hätte ich fast vergessen: du musst jeden reservierten Speicher mit free wieder feigeben. Und zwar wirklich jeden! SOnst kann es in größeren Programmen zu Memory Leaks kommen



  • nero08 schrieb:

    Hallo!

    Folgender Code führt zu einem Core dump:

    #include <assert.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
    
    char* help;
    //ich reserviere mir mit malloc mal speicher für die ersten zeichen(die abschließende \0 ist berücksichtigt).
    help = (char*) calloc(2,sizeof(char));
    if(help == NULL)
    {
     return -1;
    }
    int i = 0;
    unsigned char  *tok;
    //Nun gehe ich zeichen für Zeichen tok durch, also als ersters würde ich ein d //erhalten. 
    for(tok ="dasdsadasdasdsdasddsadasda"; *tok != '\0'; tok++)
    {
    
      // für jedes zeichen hole ich mir Speicher
      help = (char*) realloc(help, 1);   // hier ist der fehler
      if(help == NULL)
      {
        return -1;
      }
      // ich speichere an der Stelle i von help das gerade behandelte zeichen. Also // würde d an stelle 0 stehen a an der stelle 1(nächster durchlauf usw.
      *(help+i) = (int)*tok;
     
      i++;
    
     
    
    }
    help[i-1] = (int)'\0';
    
    return 0;
    }
    

    Es wird wohl an der Zeile *(help+i) = (int)*tok; liegen, aber wie würde diese Zeile korrekt lauten, wenn ich an der Stelle i in help das zeichen tok hinzufügen möchte?

    danke und lg

    Realloc will nicht die Größe,die hinzugefügt werden soll, sondern die neue Gesamtgröße.



  • hm, also wenn ich das mache so wie du es sagst bekomme ich ein warning:
    warning: assignment from incompatible pointer type [enabled by default]
    for(tok =&buffer; *tok != '\0'; tok++)

    und der core dump ist noch vorhanden.

    wenn ich die zeile : *(help+i) = (int)*tok;
    waglasse, dann hab ich keinen core dump stimmt da was nicht?

    lg



  • Was soll der hässliche int-Cast? Lasse den weg.
    Benutze durchgängig den subscript operator [], und nicht mal so mal so.
    Die Compilerwarnung ist korrekt, der Asyldämon-Schwachsinn ist purer Schrott.
    Du benutzt realloc falsch, das ist dein Hauptfehler.
    Du vergisst free.



  • mgaeckler schrieb:

    Realloc will nicht die Größe,die hinzugefügt werden soll, sondern die neue Gesamtgröße.

    Bingo.

    Also

    /* ... */
    
        help = (char*) realloc(help, i + 2);
    
        /* ... */
    

    Aber ... warum castest du das Ergebnis von realloc() ?



  • @mgaeckler, danke das wars 😃



  • Und der Rest?



  • naja, was die casts angeht, war das nur ein schnipsel eines größeren Pogrammes wo ich mit uint_8 (unsigned char) arbeite, wenn ich die casts weglasse, bekomme ich warnings.

    Das mit den frees ist ein Problem. Ist jetzt auch ein bisschen blöd zum beschreiben.

    an die Funktion wird (eigentlich ist es an anderer Datentyp, aber zur veranschaulichung nehme ich wieder char)

    void(char** dummy)
    {
    // ich hänge das help von vorhin, an dummy dran
    *dummy = help;

    }

    wenn ich jetzt danadch ein free(help) mache, geht die Information irgendwie verloren und an dummy wurde statt dem inhalt von help NULL angehängt. Was da wär was das Problem sein könnte?

    lg



  • nero08 schrieb:

    [...], wenn ich die casts weglasse, bekomme ich warnings.

    Du kompilierst C mit einem C++-Compiler.
    Der rest deines posts ist leider unverständlich. Vielleicht beschreibst du besser großzügig was du erreichen willst, nicht das Wie.



  • naja ich bekomme char** dummy übergeben und möchte in diesem dummy mein help speichern, welches ich mir wie oben beschrieben erstelle.

    Nach der Funktion soll in dummy eben genau dieses help mit den oben ermittelten inhalten gespeichert sein.

    Wenn ich allerdings for dem Ende der Funktio ein free(help) mache, befinden sich in dummy für help die falschen Inhalte.



  • Asyl-Dämon schrieb:

    Bei char tok[20]; ist tok ein Zeiger.

    Falsch

    Asyl-Dämon schrieb:

    Und "dasdsadasdasdsdasddsadasda" ist keine Speicheradresse.

    Auch falsch.

    Asyl-Dämon schrieb:

    const char buffer[] ="dasdsadasdasdsdasddsadasda";
    unsigned char *tok;
    for(tok=&buffer;tok!='\0';tok++)
    {
    

    Das & ist zuständig für die Speicheradresse.

    Das & ist an dieser Stelle falsch. Damit widersprichst du auch deiner Aussage:

    Asyl-Dämon schrieb:

    Ein dynamisch reserviertes Array lässt sich genauso verwenden wie ein Statisches. (Bis auf free)

    Für Zeichen nimmt man char als Datentyp.



  • Swordfish schrieb:

    mgaeckler schrieb:

    Realloc will nicht die Größe,die hinzugefügt werden soll, sondern die neue Gesamtgröße.

    Bingo.

    Also

    /* ... */
    
        help = (char*) realloc(help, i + 2);
    
        /* ... */
    

    Aber ... warum castest du das Ergebnis von realloc() ?

    mir stört es nach wie vor wie man: realloc hier verwendet wird. Richtig wäre:

    char *tmp;
    
    tmp = realloc(help, i + 2);
    if(tmp == NULL)
    {
        /* Das System stellt keinen Speicher mehr zur Verfügung
           Hier sollte man eine Fehlerbahandlung, z.b. */
    
        free(help);
        exit(1);
    }
    help = tmp;
    

Log in to reply