例如,我有以下结构:
struct Student{
char *studentName;
int studentAge;
struct Student *next;
};
我在链表中有许多Student结构(对于许多不同的学生)。结构中的每个变量都是strdup(除了int' s)。
现在,在完成我的程序设置的所有处理之后,我想添加一个释放所有struct实例的函数,并释放所有已经过strdup的变量。有没有办法可以快速完成这项工作?
答案 0 :(得分:2)
要使以下工作正常,您需要将next
中的strcut Student
成员初始化为NULL
,以便基本上列表中的最后一个链接为NULL
:
void freeStudents (struct Student *cur)
{
struct Student *tmp;
while (cur != NULL)
{
tmp = cur->next;
free (cur->studentName);
free (cur);
cur = tmp;
}
}
答案 1 :(得分:2)
目前还不清楚“快速”或“一下子”是什么意思。我最好的猜测是你正在寻找一个标准的库函数,在一次调用中将自动释放你想要释放的所有内存。确实有这样一个功能:exit()
。不幸的是,它的其他影响不太可能与您的目的兼容。
否则,没有标准的库函数可以实现您所追求的目标。标准库函数一般而言,特别是内存管理功能无法理解struct
的内容。例如,他们没有能力识别你的一些struct
成员是指针,他们也可能需要他们的参与者被解除分配。即使他们能够检测到这种情况,他们执行该解除分配也不安全,因为他们无法知道是否有其他指向同一动态内存的指针。
解决此类问题的常用方法是编写自己的函数来释放struct
的实例以及需要重新分配的所有成员。例如:
void free_student(struct Student *s) {
free(s->studentName);
free(s);
}
这有明显的优势,如果您修改了struct
,那么您可以根据需要更改释放函数,而不是在多个位置更改临时释放代码。
你可能会让这样一个函数做双重任务,也可以递归地释放列表中的下一个学生,但为此目的使用单独的函数(使用第一个)是更清晰的:
void free_student_list(struct Student *head) {
while (head) {
struct Student *next = head->next;
free_student(head);
head = next;
}
}
这种方法的前提是关于哪些成员可以而且应该被释放的确定性,所以你必须注意你想要释放的成员确实指向分配的内存,他们不互相别名,并且有没有假定的有效指针指向程序中其他位置的相同内存。