Reputation: 105
I have a School struct
that holds a linked list of Student struct
s and each of those Student struct
s hold a linked list of Courses struct
s. I am a bit puzzled about how I would be able to free both linked lists. I am particularly unsure about how I would free the Courses
linked list since it is within another linked list.
struct Courses {
char *courseName;
int creditValue;
Courses *next;
} Courses;
struct Student {
char *studentName;
int studentAge;
Courses *coursesList; //First course (node)
Student *next;
} Student;
struct School {
char *schoolName;
int schoolAge;
Student *studentList; //First student (node)
} School;
If someone could show me an example on how I would be able to free both the linked lists that would be great!
Upvotes: 0
Views: 87
Reputation: 144695
You should think in terms of ownership: when you free an item, you must free everything it owns, that is everything his has a pointer to that is not owned by something else.
Along these lines, each list item owns the next item, every School
owns its list of Student
s, every Student
owns its list of Courses
.
Your type definitions seem incorrect as you use the same identifier for types and variables. You should rewrite them this way:
typedef struct Course Course;
typedef struct Student Student;
typedef struct School School;
struct Course {
char *courseName;
int creditValue;
Course *next;
};
struct Student {
char *studentName;
int studentAge;
Course *courseList; //First course (node)
Student *next;
};
struct School {
char *schoolName;
int schoolAge;
Student *studentList; //First course (node)
};
The function to free everything:
void freeSchool(School *school) {
Student *student = school->studentList;
while (student) {
Course *course = student->courseList;
while (course) {
free(course->courseName); // if it was allocated
Course *nextCourse = course->next;
free(course);
course = nextCourse;
}
free(student->studentName); // if it was allocated
Student *nextStudent = student->next;
free(student);
student = nextStudent;
}
free(school->schoolName); // if it was allocated
free(school);
}
Note the similarity between the different levels. You can also split this function into separate freeSchool
, freeStudent
and freeCourse
functions that you can use to handle individual object deletion in the program.
An elegant way to handle element deletion is for the freeXXX
function to return the next element and free the node:
Courses *freeCourse(Course *course) {
Course *next = course->next;
free(course->courseName); // if it was allocated
free(course);
return next;
}
Student *freeStudent(Student* student) {
Student *next = student->next;
while (student->courseList) {
student->courseList = freeCourse(student->courseList);
}
free(student->studentName); // if it was allocated
free(student);
return next;
}
School *freeSchool(School *school) {
while (school->studentList) {
school->studentList = freeStudent(school->studentList);
}
free(school->schoolName); // if it was allocated
free(school);
return NULL;
}
Upvotes: 3