Speicherverwaltung - Laufzeitfehler - malloc()/free()/etc.



  • Jammere hier nicht rum.
    Es wurde gesagt und gezeigt, was falsch ist und wie es richtig geht.
    Wenn du das nicht umsetzt, bist du selbst schuld brauchst nicht rumjammern.
    Ich habe dir z.B. empfohlen, die getline-Schleife und die eigentliche Stringverarbeitung zu trennen, d.h. die wesentlichen Aktionen laufen dann in der Funktion ab, während die übergeordnete getline-Schleife ausschließlich für das zeilenweise Lesen zuständig ist und auch genau 1x free benötigt und nicht mehr.

    FILE *f = popen(cmd_output, "r");
    size_t st = 1000;
    char *line = malloc(st);
    
    if( !f )
      perror(cmd_output),free(line),exit(1);
    while( getline(&line, &st, f)> -1 )
    {
      verarbeite(line,&liste);
    }
    free(line);
    


  • Okay ich versuche jetzt alles so umzusetzen .. muss dann allerdings etwas früher anfangen ...

    Warum ist das so, dass man wenn man das in eine Funktion Out-Sourced nur einmal dieses free für die Funktion braucht? Werden alle anderen Variablen und Speicher nach dem Funktionsaufruf/dessen Ausführung wieder freigegeben?

    Wutz schrieb:

    Mit free der Elemente war gemeint, dass das am Ende der Funktion/des Programms geschehen soll.
    Verk. Listen sind besser durch unverk. struct-Listen bzw. struct-Arrays zu ersetzen, egal was irgendwelche Buchautoren oder Hochschulprofessoren behaupten.

    was ist eine "unverkettete struct-liste" ?

    Ich kann mir gerade nciht vorstellen, wie man eine unverkettete Liste erstellen soll, da kann man dann ja gar nicht per zähl-schleife die Elemente abfragen ..?

    LG
    Felix


  • Mod

    mekick schrieb:

    Warum ist das so, dass man wenn man das in eine Funktion Out-Sourced nur einmal dieses free für die Funktion braucht? Werden alle anderen Variablen und Speicher nach dem Funktionsaufruf/dessen Ausführung wieder freigegeben?

    Alle Variablen in deinem Programm funktionieren vollautomatisch. Nur Sachen, die du irgendwo von Hand erzeugst (malloc*), musst du auch wieder aufräumen.
    http://en.wikipedia.org/wiki/Automatic_variable

    was ist eine "unverkettete struct-liste" ?

    Das ist Wutz' poetische Beschreibung für ein Array. Die Fälle in denen eine verkettete Liste einem Array praktisch überlegen wäre, sind allesamt sehr konstruiert. Deswegen fällt die verkettete Liste als Datenstruktur in die Kategorie "theoretisch interessant, aber praktisch nicht relevant".

    *: Aber auch andere Sachen. Wenn man mit Dateien hantiert, hat man ja nur einen Zeiger auf ein FILE-Objekt. Mit open erzeugt man dann ein konkretes Objekt und mit close räumt man es wieder auf (Der Zeiger selbst fällt natürlich nach wie vor unter die automatischen Variablen).



  • SeppJ schrieb:

    mekick schrieb:

    Warum ist das so, dass man wenn man das in eine Funktion Out-Sourced nur einmal dieses free für die Funktion braucht? Werden alle anderen Variablen und Speicher nach dem Funktionsaufruf/dessen Ausführung wieder freigegeben?

    Alle Variablen in deinem Programm funktionieren vollautomatisch. Nur Sachen, die du irgendwo von Hand erzeugst (malloc*), musst du auch wieder aufräumen.
    http://en.wikipedia.org/wiki/Automatic_variable

    was ist eine "unverkettete struct-liste" ?

    Das ist Wutz' poetische Beschreibung für ein Array. Die Fälle in denen eine verkettete Liste einem Array praktisch überlegen wäre, sind allesamt sehr konstruiert. Deswegen fällt die verkettete Liste als Datenstruktur in die Kategorie "theoretisch interessant, aber praktisch nicht relevant".

    *: Aber auch andere Sachen. Wenn man mit Dateien hantiert, hat man ja nur einen Zeiger auf ein FILE-Objekt. Mit open erzeugt man dann ein konkretes Objekt und mit close räumt man es wieder auf (Der Zeiger selbst fällt natürlich nach wie vor unter die automatischen Variablen).

    DANKE! *check* 😉

    /*Edit*/

    Aber in meinem Programm weis vorher niemand wie viele Hosts und wie viele Ports pro Host vorhanden sind .. für genau solche Fälle sind doch Listen genau das richtige ..?
    Ich müsste sonst ja bei jedem neuen Host, der durchs Parsen hinzukommt, die Größe des Arrays erweitern/verändern ..?

    Lieben Gruß,
    Felix



  • DirkB schrieb:

    mekick schrieb:

    Und wie bekomme ich den Speicher des line_buffer s wieder freigegeben, wenn ich doch strtok() benötige um mir meinen gewünschten teilstring auszulesen?

    Indem du den Pointer line_buffer nicht für den Rückgabewert von strtok missbruachst sondern einen anderen dafür definierst.

    char *pointer_fuer_Rueckgabewert_von_strok; // *pc geht auch
    ....
    pointer_fuer_Rueckgabewert_von_strok = strtok(line_buffer, "\"");
    

    Das habe ich jetzt probiert gehabt und mich damit beschäftigt, jedoch ist das Problem, dass strtok() den Quell-String verändert. d.h. wenn ich folgendes schreibe:

    char *pc = strtok(line_buffer, "\"");
    

    wird der Zeiger line_buffer schon verändert.
    Ab da habe ich keine Möglichkeit mehr, den gesamten Speicher des ursprünglich allokierten line_buffer per free() freizugeben. So habe ich das bisher verstanden und da ist momentan mein Problem ...

    Liebe Grüße,
    Felix



  • mekick schrieb:

    Ich müsste sonst ja bei jedem neuen Host, der durchs Parsen hinzukommt, die Größe des Arrays erweitern/verändern ..?

    Und, wo ist das Problem?

    mekick schrieb:

    wird der Zeiger line_buffer schon verändert.
    Ab da habe ich keine Möglichkeit mehr, den gesamten Speicher des ursprünglich allokierten line_buffer per free() freizugeben.

    Und, wo ist das Problem?
    Die Leseschleife macht genau 1x malloc vor der Schleife und 1x free nach der Schleife und die Verarbeitungsfunktion in der Schleife bekommt automatisch eine Kopie des Zeigers übergeben, und mit dieser Kopie kannst du dann dein unseliges strtok aufrufen, sooft du willst.



  • 1. Ich weis noch nicht wie das mit dem größe verändern geht .. muss ich mir halt angucken ..

    2. Ich bin noch am rumtricksen, wie ich das hinbekomme mit einer funktion das zu verarbeiten, weil ich zwei listen brauche. Eine, in der die hosts alle aufgelistet sind und dann noch pro Listenelement der Hostliste eine eigene Liste, in der die Ports des jeweiligen Hosts aufgeführt sind.
    wie kann ich denn der Funktion zum verarbeiten sagen/mitgeben, dass sie pro element des Liste Arrays ein weiteres Array anlegen muss und dann halt mit daten füllen .. da hakts noch ..

    Muss ich da dann evtl in der einen verarbeite(..)-Funktion noch eine weitere funktion aufrufen um das zu realisieren? ..

    LG



  • mekick schrieb:

    char *pc = strtok(line_buffer, "\"");
    

    wird der Zeiger line_buffer schon verändert.
    Ab da habe ich keine Möglichkeit mehr, den gesamten Speicher des ursprünglich allokierten line_buffer per free() freizugeben. So habe ich das bisher verstanden und da ist momentan mein Problem ...

    Nein.

    line_buffer wird da nicht verändert. Der Bereich auf den line_buffer zeigt wird durch strtok verändert.
    Aber das ist auch erlaubt und gewünscht denn sonst hätte malloc ja keinen Sinn.



  • DirkB schrieb:

    mekick schrieb:

    char *pc = strtok(line_buffer, "\"");
    

    wird der Zeiger line_buffer schon verändert.
    Ab da habe ich keine Möglichkeit mehr, den gesamten Speicher des ursprünglich allokierten line_buffer per free() freizugeben. So habe ich das bisher verstanden und da ist momentan mein Problem ...

    Nein.

    line_buffer wird da nicht verändert. Der Bereich auf den line_buffer zeigt wird durch strtok verändert.
    Aber das ist auch erlaubt und gewünscht denn sonst hätte malloc ja keinen Sinn.

    Wenn ich jedoch genannte code-zeile so programmiere und evtl anschließend noch ein paar weitere

    pc = strtok(NULL, "\"");
    

    -Zeilen, wird durch free(line_buffer); nicht mehr der gesamte zuvor reservierte speicher freigegeben. Warum auch immer .. aber das ist fakt, denn nur da hängt mein memory leak ... an anderen stellen hab ich das manuelle allokieren aus meinem code verbannt ...



  • Trotzdem kann es nicht daran liegen.
    Sonst könntest du strtok nicht auf Arrays anwenden.

    Der Fehler liegt woanders.
    Zeig deinen Code, sonst können wir dir nicht helfen.

    Wie stellst du fest, dass nicht der gesamte Speicher freigegeben wird?


Anmelden zum Antworten