我肯定不是,但也许其中有黑魔法,所以我的问题是:
如果我有一个这样的结构:
struct mystr {
char * strp,
unsigned int foo,
};
我为它分配内存,并希望稍后释放它。我必须做吗
free(mystr_var->strp);
free(mystr_var);
或者最后一行已经用完了,free()
函数是否跟随指针并释放它们两个?
不,free不跟随指针,您需要两行。
我通常会写一个函数,比如:
void freemystr(mystr *mystr_var)
{
if (mystr_var)
{
free(mystr_var->strp);
mystr_var->strp = NULL;
free(mystr_var);
}
}
每个单独分配的内存块都必须单独释放。free()
将只释放指针指向的内存块,并且它不知道该内存的内容是什么。
因此,在您的情况下,您的做法是正确的,首先释放结构中分配的最内部内存,最后释放结构指针。
如果只释放结构指针,则结构内存将被释放。char* strp
所拥有的内存在您的程序生命周期中会成为内存泄漏。
不,不是。
它一点也不神奇,对编译器来说,它只是另一个函数调用。
问问你自己,你将如何以遵循指针的方式实现void free(void *);
,当然不会被一个包含任何的二进制数据块所欺骗。你不能。
否。它只是释放指向的块。
你需要明确地释放被引用的内存。你需要先这样做(即最有可能与你分配内存的方向相反)
否。free
不会对所有成员进行递归免费。您必须明确释放已分配内存的所有成员。
如果您了解内存是如何分配给struct的,以及free是如何工作的,这就不是问题了。
struct mystr {
char * strp,
unsigned int foo,
};
当您使用malloc&朋友,它只为成员分配内存。在您的情况下,一个char*
和一个unsigned int
。请注意,它不分配任何内存用于在char*
中存储数据。因此,在存储数据之前,必须再次为strp
分配内存。除非直接指定字符串文字,或者只使用指针strp
指向现有内存。
示例:
情况1:
struct mystr s;
s.strp = "literals"; // valid, no need to malloc
情况2:
char *p="abc";
s.strp = p; // valid, no need to malloc
在所有其他用途中,在将数据存储到strp
之前,必须为strp
分配内存。
因此,当您对结构变量调用free
时,它只释放为strp
分配的指针,而不释放strp
指向的内存。这只是因为free
没有关于strp
指向何处的信息。
请注意,在上面的两个示例中,您没有释放strp
,因为您没有在那里分配任何内存来将数据存储到strp
中。简单的规则是一个malloc/calloc/realloc
一个免费。
C99说,
free函数导致ptr指向的空间被释放,也就是说,可以用于进一步的分配。如果ptr是一个空指针,则不会发生任何操作。否则,如果参数与calloc、malloc或realloc函数先前返回的指针不匹配,或者调用free或reallock释放了空间,则行为未定义。