假设我有这个结构
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);
这不是我想做的事。
由于
答案 0 :(得分:54)
简单回答:free(testPerson)
就足够了。
请注意,只有在使用free()
,malloc
或calloc
分配内存后才能使用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
,那么会有内存泄漏,这是由firstname
和suName
指针分配的内存。
答案 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的地址相同。