Когда вы выделяете структуру, тогда установите все указатели в ней на NULL.Например, чтобы выделить структуру вашего колледжа, вам нужно установить для всех студентов значение NULL:
struct College* CollegeAlloc( char name[MAX_NAME_LEN] ) {
struct College* college = malloc( sizeof(struct College) );
if ( college ) {
for ( int i = 0; i < MAX_STUDENTS; ++i )
college->Students[i] = NULL;
memcpy( college->name, name, MAX_NAME_LEN );
}
return college;
}
В качестве альтернативы вы можете добавить поле подсчета в структуры для каждого массива, чтобы подсчитать количество элементов массива, которыефактически используются.
Если вы установите для элемента массива значение NULL, когда оно не используется, вы можете сначала освободиться снизу вверх.
void FamilyFree( struct Family *fam ) {
free( fam );
}
void StudentFree( struct Student *student ) {
if ( student ) {
FamilyFree( student->fam );
free( student );
}
}
void CollegeFree( struct College *college ) {
if ( college ) {
for ( int i = 0; i < MAX_STUDENTS; ++i )
StudentFree( college->Students[i] );
free( college );
}
}
void SystemFree( struct System *sys ) {
if ( sys ) {
for ( int i = 0; i < MAX_COLLEGES; ++i )
CollegeFree( sys->Colleges[i] );
free( sys );
}
}
Обратите внимание, что это предполагает, что нет совместного использования указателей, например, один и тот же учащийся находится в более чем одном колледже (когда реализация выделила только одну структуру для каждого студента),или когда есть два родных брата, которые имеют ту же самую структуру семьи.(структура семьи не очень хорошо моделирует семьи, например, одинокие родители, разведенные, вступившие в повторный брак, гомосексуальные родители, законные опекуны).Когда структуры могут использоваться совместно, вы можете поместить счетчик ссылок в структуру и освободить его, только когда он уменьшен до нуля.