C - 释放结构

时间:2012-11-27 18:36:38

标签: c struct malloc

假设我有这个结构

typedef struct person{
    char firstName[100], surName[51]
} PERSON;

我正在通过malloc分配空间并用一些值填充

PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));
strcpy(testPerson->firstName, "Jack");
strcpy(testPerson->surName, "Daniels");

释放该结构占用的所有内存的正确和安全的方法是什么?是“免费的(testPerson);”够了还是我需要逐个释放每个结构的属性?

它引出了另一个问题 - 结构如何存储在内存中?我注意到一种奇怪的行为 - 当我尝试打印结构地址时,它等于它的第一个属性的地址。

printf("Structure address %d == firstName address %d", testPerson, testPerson->firstName);

这意味着这一点     免费(testPerson) 应该等于这个     自由(testPerson->的firstName);

这不是我想做的事。

由于

7 个答案:

答案 0 :(得分:54)

简单回答:free(testPerson)就足够了。

请注意,只有在使用free()malloccalloc分配内存后才能使用realloc

在你的情况下,你只有testPerson的malloced内存,所以释放就足够了。

如果您使用char * firstname , *last surName,那么在这种情况下,您必须已经分配了内存以及为什么必须单独释放每个成员。

这也应该是相反的顺序;这意味着,为元素分配的内存稍后完成,所以free()首先将它释放到对象。

释放每个元素,您可以看到如下所示的演示:

typedef struct Person
{
char * firstname , *last surName;
}Person;
Person *ptrobj =malloc(sizeof(Person)); // memory allocation for struct
ptrobj->fistname = malloc(n); // memory allocation for firstname
ptrobj->surName = malloc(m); // memory allocation for surName

.
. // do whatever you want

free(ptrobj->surName);
free(ptrobj->firstname);
free(ptrobj);

这背后的原因是,如果你先释放ptrobj,那么会有内存泄漏,这是由firstnamesuName指针分配的内存。

答案 1 :(得分:5)

因为您将struct定义为由char数组组成,所以两个字符串 结构并释放struct就足够了,也没有释放struct但保留数组的方法。对于这种情况,您可能希望执行struct { char *firstName, *lastName; }之类的操作,但是您需要单独为名称分配内存并处理何时释放 内存的问题。

除此之外:在struct被释放后,您是否希望保留名称??

答案 2 :(得分:4)

首先,您应该知道,在以下情况下定义和分配内存时会分配多少内存。

   typedef struct person{
       char firstName[100], surName[51]
  } PERSON;
  PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));

1)sizeof(PERSON)现在返回151个字节(不包括填充)

2)151字节的内存在堆中分配。

3)要免费,请免费拨打(testPerson)。

但是如果您将结构声明为

  typedef struct person{
      char *firstName, *surName;
  } PERSON;
  PERSON *testPerson = (PERSON*) malloc(sizeof(PERSON));

然后

1)sizeof(PERSON)现在返回8个字节(不包括填充)

2)需要通过调用malloc()或calloc()为firstName和surName分配内存。像

        testPerson->firstName = (char *)malloc(100);

3)要释放,首先释放结构中的成员而不是释放结构。即,            自由(testPerson->的firstName);            自由(testPerson->姓);            自由(testPerson);

答案 3 :(得分:3)

这样您只需要释放结构,因为字段是具有静态大小的数组,这些数组将作为结构的一部分进行分配。这也是您看到的地址匹配的原因:数组是该结构中的第一件事。如果您将字段声明为char *,则必须手动malloc并释放它们。

答案 4 :(得分:2)

Mallocs和frees需要配对。

malloc抓住了一大块内存,足以让人满意。

当你释放你告诉malloc时,不再需要从“here”开始的内存,它知道它分配了多少并释放它。

是否致电

 free(testPerson) 

 free(testPerson->firstName)

所有free()实际收到的是一个地址,相同的地址,它无法分辨你调用的是什么。如果使用free(testPerson),你的代码会更清晰 - 它显然与malloc匹配。

答案 5 :(得分:2)

您无法释放未动态分配的类型。尽管数组在语法上相似(int* x = malloc(sizeof(int) * 4)可以与int x[4]相同的方式使用),但调用free(firstName)可能会导致后者出错。

例如,请使用以下代码:

int x;
free(&x);

free()是一个接收指针的函数。 &x是一个指针。这段代码可能会编译,即使它只是无法工作。

如果我们假装所有内存都以相同的方式分配,x是"已分配"根据定义,"释放"在第二行,然后"释放"在范围结束后再次。你不能两次释放相同的资源;它会给你一个错误。

这甚至没有提到这样一个事实:由于某些原因,如果不关闭程序,您可能无法在x释放内存。

tl; dr:刚刚释放struct,你就没事了。 不要在阵列上免费拨打电话;只在动态分配的内存上调用它。

答案 6 :(得分:2)

free是不够的,free只是将内存标记为未使用,结构数据将一直存在直到覆盖。为安全起见,请在NULL之后将指针设置为free

例如:

if (testPerson) {
    free(testPerson);
    testPerson = NULL;
}

struct类似于数组,它是一块内存。您可以通过其偏移量访问struct成员。第一个struct的成员放在偏移0,因此第一个struct的成员地址与struct的地址相同。