2

例如,我有以下结构:

 struct Student{
     char *studentName;
     int studentAge;
     struct Student *next;
  };

我在链接列表中有许多 Student 结构的实例(对于许多不同的学生)。结构中的每个变量都是 strdup 的(int 除外)。

现在,在完成我的程序要执行的所有处理之后,我想添加一个函数,该函数将释放所有结构实例并释放所有已被 strdup 处理的变量。有没有办法让我快速做到这一点?

4

2 回答 2

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;
    }
}

这种方法基于确定哪些成员可以并且应该被释放,因此您必须注意您打算释放的成员确实指向分配的内存,它们不会相互别名,并且没有假定-指向程序中其他地方的相同内存的有效指针。

于 2016-01-24T21:47:18.573 回答
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;
    }
}
于 2016-01-24T21:17:43.350 回答