C Freigabe von Speicher nach strdup()
Mache ich eine Lektion aus der Learn C the Hard way online-Kurs. Im code-Beispiel unten, ich verstehe nicht, warum die zwei free()
Anrufe notwendig sind. Ich dachte, man bräuchte nur zu rufen free()
einmal, weil nur eine malloc()
Auftritt. Könnte jemand klären, warum brauchen wir zwei?
Wenn ich kommentieren free(who->name);
dann valgrind
sagt mir, dass ich verloren habe, ein Stück 'a-Speicher, wie so;
LEAK SUMMARY:
definitely lost: 21 bytes in 2 blocks
Hier der code:
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
int height;
int weight;
};
struct Person *Person_create(char *name, int age, int height, int weight)
{
struct Person *who = malloc(sizeof(struct Person));
assert(who != NULL);
who->name = strdup(name);
who->age = age;
who->height = height;
who->weight = weight;
return who;
}
void Person_destroy(struct Person *who)
{
assert(who != NULL);
free(who->name); /* Why this one??! */
free(who);
}
int main(int argc, char *argv[])
{
//make two people structures
struct Person *joe = Person_create(
"Joe Alex", 32, 64, 140);
struct Person *frank = Person_create(
"Frank Blank", 20, 72, 180);
//destroy them both so we clean up
Person_destroy(joe);
Person_destroy(frank);
return 0;
}
Denn auch strdup() Speicher reserviert, dann muss es freigegeben werden (siehe doc).
Lesen Sie die Dokumentation der standard-Funktion schneller als bitte auf DAMIT !
eine standard-Funktion kann erwähnt werden, dass in einigen anderen standard als C99. Posix ist ein solcher standard.
strdup
ist ein malloc
im Unglück.Lesen Sie die Dokumentation der standard-Funktion schneller als bitte auf DAMIT !
strdup
ist kein Standard-C-Funktion, allerdings ist es im POSIX. (Keine Standard-C-Funktionen geben einen Zeiger, erfordert die Befreiung, andere als malloc
, calloc
, realloc
).eine standard-Funktion kann erwähnt werden, dass in einigen anderen standard als C99. Posix ist ein solcher standard.
InformationsquelleAutor Andy J | 2014-07-29
Du musst angemeldet sein, um einen Kommentar abzugeben.
strdup(3) ist dokumentiert als
BTW, wie Matt McNabb kommentiert
strdup
ist im Posix-standard, nicht in der C99-Sprache-Spezifikation.Natürlich
free
nur gibt den Speicher zone, übergeben Sie es (es ist nicht magisch und indirekt frei jede zone wies im inneren des memory zone, die Sie übergeben haben). Wieder, free(3) sagt:Lesen Sie mehr über C dynamic memory allocation. Wenn Sie dies nicht möchten, erfahren Sie mehr über garbage collection. Mit C unter Linux und einige andere Systeme, Sie könnten auch mit Boehm konservativen garbage collector. Werde Sie Sie dann verwenden
GC_MALLOC
- und/oderGC_MALLOC_ATOMIC
stattmalloc
, undGC_STRDUP
stattstrdup
und Sie werden sich nicht die Mühe überfree
(man könnte manchmalGC_FREE
wenn gewünscht). Ich finde es sehr nützlich, aber es hat einige Nachteile (langsamer alsmalloc
, und keine explizite Garantie über die Freigabe von Speicher,...).Lesen über Speicher Korruption, und memory leaks
BTW, sollten Sie zuerst kompilieren Sie Ihr Programm mit allen Warnungen und debug-Informationen (z.B.
gcc -Wall -g
). Dann könnten Sie Ihre debugger (gdb
) setzen Sie einen Haltepunkt inmalloc
nachmain
erreicht wurde, und zu sehen, wennmalloc
genannt wird. Sie werden sehen, dassstrdup
ruftmalloc
....FYI, auf Linux
malloc
realisiert mmap(2) -und manchmal auch die alten sbrk(2)- syscalls -um "große" Speicher-Regionen (von mehreren kilobytes oder sogar megabytes), undfree
kann manchmal rufen munmap(2) -für diese großen Regionen - aber meistens ist es justs daneben ein freier block als wiederverwendbare, so dass block können wiederverwendet werden, in einigen Zukunft Aufrufemalloc
. Damit ein Programm tunmalloc
undfree
möglicherweise nicht alle freigeben es bisher verwendeter Speicher, um den kernel. Siehe auch diese Frage über Speicher-Fragmentierung.InformationsquelleAutor Basile Starynkevitch