我试图通过试验各种案例来熟悉C中的链接列表,我有一个问题。我编写了这段代码,我不确定哪种方法可以释放动态分配的内存。只是免费(S);或者我必须免费写(Top);如果是的话,这两个命令的顺序是否重要?另外,除此之外,这段代码是否正确编写?如果你不介意的话,我想要一个彻底的解释,我没有编码任何东西5年。
#include <stdlib.h>
#include <stdio.h>
typedef char StackType;
typedef struct StackNodeTag
{StackType T;
struct StackNodeTag *Link;
} StackNode;
typedef struct StackTag
{struct StackNodeTag *Top;
} Stack;
typedef Stack *StackPointer;
int main (void)
{StackPointer S;
S = malloc (sizeof (Stack));
S->Top = malloc (sizeof (StackNode));
S->Top->T = 'c';
S->Top->Link = NULL;
free (S->Top);
free (S);
return 0;
}
答案 0 :(得分:1)
是的,您必须释放使用malloc
或类似功能分配的所有内容,订单确实很重要。
由于您在另一个项目中有动态分配的项目,因此您必须从内到外解放。如果您在S
之前释放S->Top
,则可能会导致内存泄漏,因为您在处理内容时释放了包含malloc
数据的内存。
答案 1 :(得分:1)
malloc
的通话次数应与free
的通话次数相同。
你所拥有的将会正常运作。就订单而言,您只需要确保可以访问要释放的内存。例如,如果您先执行free(S)
,则在代码中,由于free(S->Top)
不再指向有效内存,因此您无法成功调用S
。
答案 2 :(得分:0)
此代码是正确的。每个malloc()调用都应该有一个相应的free()调用,所以你在这里需要两个免费调用--S和Top。
在大多数情况下,您对free()的调用顺序无关紧要。每个malloc()调用都返回一个指针。只要使用malloc返回的相同指针调用free,就可以按任意顺序释放数据。
但是,在这种情况下,free()调用的顺序很重要,因为您对Top的唯一引用是通过S.一旦释放S,就不应该引用存储在S引用的结构中的任何数据。
在许多实现中,如果在释放后直接访问释放结构中的数据,您将会很幸运,数据仍然存在。但是,这是不好的做法,因为无法保证数据保持原样。因此,您的免费电话(S-> Top)必须在免费(S)之前。
例如,释放这些数据的同样有效的方法是1)将StackNode指针保存到临时变量,2)free S,以及3)使用临时变量释放Top。但是,你写这个的方式更好,因为它更简单。
答案 3 :(得分:0)
您对malloc和free的使用是正确的,并且是唯一有效的订单。
S指向的堆栈必须存在才能访问/分配其元素Top。此外,如果S在S-> Top之前被释放,你将孤立S-> Top所指向的内存,无法访问或释放它(如果Stack指向的话,你不能释放S-&gt; Top; S不再存在。)
我还建议纠正一些风格问题,以使您的代码更清晰。
// Original
int main (void)
{StackPointer S;
..
}
使用与开括号位于同一行的代码很难阅读。并不是说它无法被理解,只是它一眼就看不出来。
// Easier to read
int main(void)
{
StackPointer S;
..
}
/* Alternate Style, many will say to use
the above for functions and this for all
other bracket notation (structs/unions, control flow) */
int main(void) {
StackPointer S;
..
}
这是两种常用的风格。
typedef Stack *StackPointer;
...
StackPointer S;
这是非常不必要的,需要读者查看StackPointer是什么。
Stack *S;
这不需要typedef,很明显S是指向Stack类型的指针。
此外,由于堆栈可能始终存在,您可以静态创建它(如果您愿意)。这也将改变您访问其成员的方式
修改后的代码
#include <stdlib.h>
#include <stdio.h>
typedef char StackType;
typedef struct StackNodeTag {
StackType T;
struct StackNodeTag *Link;
} StackNode;
typedef struct {
StackNode *Top;
} Stack;
int main (void)
{
Stack S;
S.Top = (StackNode *) malloc(sizeof(StackNode));
S.Top->T = 'c';
S.Top->Link = NULL;
free (S.Top);
return 0;
}