我敢肯定它没有,但也许里面有黑魔法,所以这是我的问题:
如果我有这样的结构:
struct mystr {
char * strp,
unsigned int foo,
};
我为它分配内存并想稍后释放它。我必须做吗
free(mystr_var->strp);
free(mystr_var);
或者最后一行是否足够,free()
函数是否跟随指针并释放它们两个?
不,免费不遵循指针,您需要这两行。
我通常写一个函数,如:
void freemystr(mystr *mystr_var)
{
if (mystr_var)
{
free(mystr_var->strp);
mystr_var->strp = NULL;
free(mystr_var);
}
}
每个单独分配的内存块都必须单独释放。free()
只会释放指针指向的内存块,并且它不知道该内存的内容是什么。
因此,在您的情况下,您通过首先释放结构中分配的最里面的内存并最终释放结构指针来以正确的方式进行操作。
如果您只是对结构指针执行 free 操作,则结构内存将被释放。, 持有的内存char* strp
成为程序生命周期中的内存泄漏。
不,它没有。
这根本不是魔法,对编译器来说它只是另一个函数调用。
问问你自己,你将如何void free(void *);
以一种遵循指针的方式实现,当然不会被一个包含任何内容的二进制数据块所愚弄。你不能。
不,它只是释放指向的块。
您需要显式释放引用的内存。您需要先执行此操作(即很可能与分配内存的方式相反)
不free
,不会为所有成员免费递归。您必须显式释放已为其分配内存的所有成员。
如果您了解如何为 struct 分配内存以及 free 是如何工作的,这将不是问题。
struct mystr {
char * strp,
unsigned int foo,
};
当您使用 malloc 和朋友分配内存时,它只为成员分配内存。在你的情况下 onechar*
和 one 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
struct 变量时,它只释放分配给的指针strp
,而不释放strp
. 这仅仅是因为free
没有关于strp
指向何处的信息。
请注意,在上面的两个示例中,您没有释放strp
,因为您没有在那里分配任何内存来将数据存储到strp
. 简单的规则是一送一malloc/calloc/realloc
。
C99 说,
free 函数会导致 ptr 指向的空间被释放,也就是说,可用于进一步分配。如果 ptr 是空指针,则不会发生任何操作。否则,如果参数与 calloc、malloc 或 realloc 函数先前返回的指针不匹配,或者如果空间已通过调用 free 或 realloc 被释放,则行为未定义。