malloc und free
-
ok, dann ist mir das jetzt - glaube ich - klar. Aber weil ichs nur glaube:
Gibt es ein programm, was memory leaks erkennt? oder anders: wie kann ich denn am ende sicher sein, dass ich alles wieder freigegeben habe was ich mal reserviert habe? Was ist da die beste methode?
-
Unter Linux kann ich valgrind empfehlen. Allgemein (portabel) kannst du malloc() und free() wrappen und einfach bei malloc() einen Zähler inkrementieren und bei free() wieder dekrementieren.
(irgendwie habe ich das alles im halbfertigen FAQ-Prototypen... den sollte ich echt mal fertigmachen :()
-
bham schrieb:
Ist es generell ein designfehler, wenn funktionen variablen zurückgeben, die dynamisch speicher zugewiesen bekommen haben?
Nein, sonst wären malloc & friends Designfehler
Wenn du eine Funktion anbietest, die dynamischen Speicher reserviert und zurückliefert, dann obliegt es an dir, in der Dokumentation darauf hinzuweisen, dass der Benutzer den reservierten Speicher freigeben muss (oder eine bestimmte Funktion aufrufen soll, die den Speicher aufräumt). Mehr kannst du da nicht machen.
-
Tim schrieb:
(irgendwie habe ich das alles im halbfertigen FAQ-Prototypen... den sollte ich echt mal fertigmachen :()
Done: http://www.c-plusplus.net/forum/viewtopic-var-t-is-206606.html
-
Tim schrieb:
Done: http://www.c-plusplus.net/forum/viewtopic-var-t-is-206606.html
if ( temp != NULL )
Wieso testest Du bei realloc explizit? NULL ist doch 0 ist doch boolean 0.
Weitergehend: Der Wrapper ist zwar lustig, aber der echte Speicherverbrauch ist ja auch interessant (besonders, wenn's knapp wird) - scheitert wohl daran, daß man free() nicht entlocken kann, wieviel es freigegeben hat - oder?
-
pointercrash() schrieb:
Weitergehend: Der Wrapper ist zwar lustig, aber der echte Speicherverbrauch ist ja auch interessant (besonders, wenn's knapp wird) - scheitert wohl daran, daß man free() nicht entlocken kann, wieviel es freigegeben hat - oder?
kannste so machen, wenn du mitzählen willst:
#include <stdio.h> #include <stdlib.h> size_t total = 0; void *my_malloc (size_t s) { size_t *i = malloc (s + sizeof(int)); if (!i) { printf ("heap exhausted"); } else { *i = s; total += s; printf ("%u/%u bytes malloc'd\n", s, total); } return i+1; } void my_free (void *p) { size_t *i; if (p) { i = p; i--; total -= *i; printf ("%u/%u bytes freed\n", *i, total); free (i); } } int main() // demo { int *p = my_malloc (10*sizeof(*p)); double *q = my_malloc (12*sizeof(*q)); my_free (p); my_free (q); }
-
ääh, kleiner fehler, in der zeile: size_t *i = malloc (s + sizeof(int));
muss das sizeof so sein: sizeof(size_t)
-
pointercrash() schrieb:
Wieso testest Du bei realloc explizit? NULL ist doch 0 ist doch boolean 0.
Hmm, ich denke um es eindeutig zu machen. Geschmackssache. Normalerweise mach ich das auch nicht.
pointercrash() schrieb:
Weitergehend: Der Wrapper ist zwar lustig, aber der echte Speicherverbrauch ist ja auch interessant (besonders, wenn's knapp wird) - scheitert wohl daran, daß man free() nicht entlocken kann, wieviel es freigegeben hat - oder?
Jo, das Ding sollte erstens nicht zu weit führen, und zweitens portabel sein. Und dann müsste man für jede Allokation gleich noch in einer Liste merken was man man reserviert hat, etc. Dazu sind dann Tools wie valgrind besser.
-
fehlerteufel-freak schrieb:
ääh, kleiner fehler, in der zeile: ...
Den hätte ich sogar gesehen
, mir ist aber nicht ganz klar, was im free- wrapper in den Zeilen
i = p;
wirklich passiert. Da wird ein void* implizit auf size_t* gecastet und und schwuppdiwupp kriege ich darüber die Größeninformation?
Wo ist der Gimmick, den ich jetzt nicht abraffe?Kannst Du's mir schonend beibringen?
-
pointercrash() schrieb:
Wo ist der Gimmick, den ich jetzt nicht abraffe?
Kurz: Er reserviert immer ein size_t mehr Speicher als angefordert, dort speichert er die reservierte Länge ab und gibt dann einen Zeiger auf das nächste Element weiter. Beim free() halt dann rückwärts.
-
Tim schrieb:
Kurz: Er reserviert immer ein size_t mehr Speicher als angefordert, dort speichert er die reservierte Länge ab und gibt dann einen Zeiger auf das nächste Element weiter. Beim free() halt dann rückwärts.
Stimmt, deswegen hätte es mit dem sizeof(int) brutalen Ärger gegeben, hab's auch gerade gesehen
-
pointercrash() schrieb:
Stimmt, deswegen hätte es mit dem sizeof(int) brutalen Ärger gegeben, hab's auch gerade gesehen
da sind noch mehr fehler drin, aber das prinzip ist ja jetzt klar.