在C中正确释放内存的方法

时间:2014-11-17 14:19:39

标签: c memory-management free

所以我试图理解C中的内存管理的整个概念,我得到了这段代码:

int main(int argc, int *argv[]) {
  item *x = NULL;
  x = (item *) malloc (sizeof(item));

  ...

  free_item(&x);
}

void free_item(item **x) {
  free(*x);
  *x = NULL;
}

其中item是早期定义的结构。我感到困惑的地方是free_item(&x);,因为当我写free_item(x);并将函数更改为:

void free_item(item *x) {
  free(x);
  x = NULL;
}

代码似乎与前一代码的工作方式相同。

那么,有什么区别吗?如果没有,是否有任何理由,为什么有人会将一个结构指针的地址发送给一个函数,从而释放这个结构?

5 个答案:

答案 0 :(得分:3)

是。首先,我认为你修改过的函数中有一个拼写错误。它应该是:

void free_item(item *x) {
  free(x);
  x = NULL;
}

现在,为了差异。 free调用将成功,因为它所期望的是一个"指向类型的指针"在堆上动态分配的数据的变量。

第二部分x = NULL将无法按预期工作。请记住,在C中,当将参数传递给函数时,我们总是按值传递,而不是通过引用传递。您正在传递变量的副本,因此x = NULL只会将x临时自动分配的副本设置为NULL,而不是作为传递的实际变量参数。

您更改的原始功能正确地完成了两个部分。

答案 1 :(得分:0)

  1. 在第一种情况下,要修改指针变量content的{​​{1}},您需要使用引用传递。这就是x和双指针被用于&xfree()分配的记忆的原因。这是正确的。

  2. 在第二种情况下,将创建main()的函数本地副本并将其传递给x,这对free_item()中的x没有影响}}。 main()的范围仅在x = NULL;内。

答案 2 :(得分:0)

在您的第一个示例中,您使用类型指针的参数调用free_item指向项目的指针(假设item **x参数)。

在第二个示例中,将点值(main::x)复制到free_item::x(不同范围),并将复制的值设置为NULL(之后丢弃值)。

printf("%p\n", x);添加到main()的末尾(free_item之后)。

在第一个示例中,您会看到NULL,第二个x仍会设置为先前存储在那里的地址。

在第一个示例中,假设您的指针位于地址0x00400000上,它指向在0x00410000分配的内存。

0x00400000 0x00410000 <- x is stored here
0x00400004 0x00400000 <- tmp described later; point to x
...
0x00410000 .......... <- x points here; start of item - returned by malloc

当您致电item **tmp = &x时,您会看到它将包含地址0x00400000(并且tmp本身将存储在不同的内存地址中。)

然后在free_item()

free(*tmp);     // The same as free(0x00410000)
*tmp = NULL;    // Modifies data at 0x00400000 = NULL

答案 3 :(得分:-1)

使用free时,传递指针,而不是指针的值。

所以,如果你使用

 item *x

,你应该使用

free(x)

答案 4 :(得分:-2)

  1. x = (item *) malloc (sizeof(item));是不必要的。 x = malloc(sizeof(item));就足够了。
  2. 2

    void free_item(item *data){
      free(data);
    }
    

    这是正确的方法。

    1. 编写惯用的C代码。没有区别,但很难进行调试和维护。
    2. 我会写free_item(x);而不是free_item(&x)并且free_item(item **x)