Speicherverwaltung und Realloc

8

Ich gehe mit Valgrind durch mein Programm, um Speicherlecks zu finden. Hier ist einer, bei dem ich nicht sicher bin, was ich damit anfangen soll.

%Vor%

Hier ist der Code:

%Vor%

Sollte ich hier etwas in Bezug auf die Speicherverwaltung tun?

    
Scott 23.10.2009, 06:50
quelle

6 Antworten

11

Das Problem ist, dass, wenn realloc() fehlschlägt, die Funktion NULL zurückgibt, aber der ursprüngliche Block immer noch zugewiesen wird. Sie haben jedoch gerade den Zeiger auf diesen Block überschrieben und können ihn nicht mehr freigeben (oder verwenden).

    
Michael Burr 23.10.2009, 06:57
quelle
2

Wenn realloc () fehlschlägt, wird null zurückgegeben und der ursprüngliche Block wird nicht freigegeben . Diese Zeile:

%Vor%

überprüft den Rückgabewert nicht. Wenn also realloc () fehlschlägt, wird null in Hash- & gt; -Spalten geschrieben und der ursprüngliche Block wird durchgesickert.

    
sharptooth 23.10.2009 06:56
quelle
2

Valgrind sagt nicht, dass das Leck in der realloc -Zeile passiert - es sagt, dass der Speicher, der von dieser realloc -Zeile zugeteilt wurde, der Speicher ist, der irgendwann geleakt wird. Valgrind weiß nicht, wo es ist - es weiß nur, dass du keinen Bezug mehr zu diesem Speicher hast, also wäre es unmöglich, free it. (Das OP kann das wissen, aber es ist klar, dass viele der Antworter dies nicht tun!)

Kurz gesagt, der Code, den Sie eingefügt haben, verursacht das Problem nicht (obwohl das Problem, das Michael Burr aufwirft, definitiv real ist, aber da Sie nicht einmal nach einem NULL suchen, das von realloc zurückgegeben wurde. .)

Irgendwo in deinem Code sollte ein free(Hash->Columns) sein, das jetzt nicht da ist. Finde diesen Ort - wahrscheinlich kurz bevor %%_de% selbst freigegeben wurde - und füge ihn hinzu.

    
caf 23.10.2009 13:13
quelle
1

Nicht sicher, dass dies das Problem ist, aber es ist möglicherweise problematisch. Auf der Hilfeseite für realloc() :

  

RÜCKGABEWERT

     

Nach erfolgreichem Abschluss mit einer Größe ungleich 0 gibt realloc() einen Zeiger auf den (möglicherweise verschobenen) zugewiesenen Speicherplatz zurück. Wenn die Größe 0 ist, wird entweder ein Nullzeiger oder ein eindeutiger Zeiger zurückgegeben, der erfolgreich an free() übergeben werden kann. Wenn nicht genügend Arbeitsspeicher verfügbar ist, gibt realloc() einen Nullzeiger zurück und setzt errno auf [ENOMEM].

Wenn nicht genügend Platz für das erweiterte Objekt vorhanden ist, wird das alte Objekt noch gültig und nicht freigegeben, aber realloc() gibt NULL zurück. Sie sollten also das Rückgabeergebnis von realloc() in einer separaten Variablen speichern, diese Variable für NULL überprüfen und, falls dies nicht der Fall ist, diese Hash->Columns zuweisen.

    
Chris Lutz 23.10.2009 06:58
quelle
1

Aha-asveikaus Kommentar:

  

Aber wenn das das Leck wäre, das er in Valgrind sieht, würde es eine Null-Dereferenz geben und er würde zusammenbrechen. Ich denke, es gibt Code, den er nicht zur Verfügung stellt, der ein Leck hat.

hat mich zu einem anderen Problem geführt - die Datenstruktur, die Sie in der Größe ändern, enthält Zeiger auf Strings, die mit strdup() zugewiesen sind. Wenn Ihr realloc() -Aufruf die Zuweisung kleiner macht, werden Sie diese Zeiger verlieren, ohne sie vorher ordnungsgemäß zu löschen. Ich glaube, dass asveikau richtig ist, worüber sich valgrind beschweren kann.

    
Michael Burr 23.10.2009 07:04
quelle
0

Unter Mac OS X und FreeBSD et al. Sie haben auch die Funktion reallocf ():

%Vor%     
hansu 23.10.2009 07:38
quelle