free()函数会释放指针吗?

6
我很确定它不会,但也许里面有黑魔法,所以这是我的问题:
如果我有一个像这样的结构体:
struct mystr {
    char * strp,
    unsigned int foo,
};

我分配了内存,并希望稍后释放它。我需要做什么?
free(mystr_var->strp);
free(mystr_var);

或者最后一行就足够了,free()函数是否会跟随指针并释放它们两个?


1
可能是重复问题:您可以在此处找到详细答案https://dev59.com/Y2Yr5IYBdhLWcg3wi6zd#13590879 - Omkant
好的,谢谢。我认为这个问题现在已经得到了尽可能好的回答。 - musicmatze
6个回答

5

不,免费版本不支持指针,你需要两行代码一起使用。

我通常会编写如下函数:

void freemystr(mystr *mystr_var)
{
    if (mystr_var)
    {
        free(mystr_var->strp);
        mystr_var->strp = NULL;
        free(mystr_var);
    }
}

4

每个单独分配的内存块都必须单独释放。 free() 只会释放指针指向的内存块,而不知道该内存块的内容。

因此,在您的情况下,通过首先释放结构中最内层分配的内存,最后释放结构指针的方式是正确的。

如果您只对结构指针执行 free 操作,则结构内存将被释放。由 char* strp 持有的内存成为程序生命周期中的内存泄漏。


3

不,它并不是魔法。

对于编译器来说,这只是另一个函数调用而已。

请问你会如何实现void free(void *);,以便按照指针的方式进行操作,当然不能被二进制数据块所欺骗,这是需要考虑的问题。但你无法做到。


2

不,free 不会对所有成员进行递归释放。您必须明确释放您已分配内存的所有成员。

如果您了解结构体如何分配内存以及如何使用 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之前为其分配内存。
因此,当您在结构变量上调用free时,它仅释放为strp分配的指针,而不是指向strp的内存。 这只是因为free没有关于strp指向何处的信息。
请注意,在上述两个示例中,您不需要释放strp,因为您没有在那里分配任何内存来存储数据到strp。简单的规则是一个malloc/calloc/realloc对应一个free

2

不,它只是释放了指向的块。

您需要显式释放引用的内存。您需要首先执行此操作(即最可能与分配内存的相反方向)。


0

C99规定,

free函数会释放由ptr指向的空间,即使其可用于进一步分配。如果ptr是一个空指针,则不执行任何操作。否则,如果参数与之前由calloc、malloc或realloc函数返回的指针不匹配,或者该空间已被调用free或realloc释放,则行为是未定义的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接