如何正确安全地释放()所有内存使用 C 中的嵌套结构?
How to correctly and safely free() all memory used a nested struct in C?
我嵌套了四层不同的结构。代码如下:
typedef struct System system;
typedef struct College college;
typedef struct Student student;
typedef struct Family family;
#define MAX_COLLEGES 10
#define MAX_NAME_LEN 32
#define MAX_STUDENTS 10
struct System {
college *Colleges[MAX_COLLEGES];
};
struct College {
char name[MAX_NAME_LEN];
student *Students[MAX_STUDENTS];
};
struct Student {
char name[MAX_NAME_LEN];
int id;
family *fam; //was typo familiy
};
struct Family {
char fatherName[MAX_NAME_LEN];
char motherName[MAX_NAME_LEN];
};
并且我给它们都分配了内存(我不确定是否分配正确),如下:
system *collegeSys = malloc(sizeof(system));
college *colleges = malloc(sizeof(college));
student *students = malloc(sizeof(student));
family *fam = malloc(sizeof(family));
// then the following is initialization
...
...
...
现在,我需要删除 collegeSys
结构以及与之关联的所有内容。所以,我不知道我是否可以只释放第一个 collegeSys
结构而不释放任何其他结构,如下所示:
free(collegeSys);
或者为了 "delete anything associated with it",我必须自下而上释放所有内容,如下所示:
free(fam);
free(students);
free(colleges);
free(collegeSys);
或者为此,我什至必须释放每个结构中包含的所有内容并自下而上释放它们,如下所示:
free (fam -> fatherName);
free (fam -> motherName);
free (fam);
free (students -> name);
free (students -> id);
free (students -> fam);
free (students)
.
. till
.
free (collegeSys -> colleges);
free (collegeSys);
哪一种是释放内存的正确且安全的方法?或者 none 是?
我不太明白指针数组的意义,它可以用指针来完成。
定义:
struct System {
college *Colleges;
};
struct College {
char name[MAX_NAME_LEN];
student *Students;
};
struct Student {
char name[MAX_NAME_LEN];
int id;
familiy *fam;
};
struct Family {
char fatherName[MAX_NAME_LEN];
char motherName[MAX_NAME_LEN];
};
分配和初始化:
system *collegeSys = malloc(sizeof(*collegeSys));
collegeSys->colleges = malloc(MAX_COLLEGES * sizeof(*(collegeSys->colleges)));
collegeSys->colleges->students = malloc(MAX_STUDENTS * sizeof(*(collegeSys->colleges->students)));
collegeSys->colleges->students->fam = malloc(sizeof(*(collegeSys->colleges->students->fam)));
释放:
free(collegeSys->colleges->students->fam);
free(collegeSys->colleges->students);
free(collegeSys->colleges);
free(collegeSys);
更新:
Like I want to have struct student A, B, C, D under a struct college
collegeSys->colleges->students[0] = A;
collegeSys->colleges->students[1] = B;
collegeSys->colleges->students[2] = C;
collegeSys->colleges->students[3] = D;
应该做。
如果您有 student
数组,您可以使用 memcpy
或复制到 loop
。
struct student stud[MAX_STUDENTS] = {...};
memcpy(collegeSys->colleges->students[2], stud, MAX_STUDENTS);
或
for (int i = 0; i< MAX_STUDENTS; i++)
collegeSys->colleges->students[i] = stud[i];
注:
您可以将数组分配给 collegeSys->colleges->students
,在这种情况下您不需要动态内存分配或释放。
// collegeSys->colleges->students = malloc(MAX_STUDENTS * sizeof(*(collegeSys->colleges->students))); //Leaks memory
collegeSys->colleges->students = stud;
//free(collegeSys->colleges->students); //wrong
分配一个结构然后将其中的所有指针设置为 NULL。
例如,要分配你的 College 结构,你需要将所有学生设置为 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 );
}
}
请注意,这假设 没有共享 指针,例如同一个学生在不止一所大学(当实施只为每个学生分配一个结构时),或者当有两个兄弟姐妹共享相同的家庭结构时。 (家庭结构不能很好地模拟家庭,例如单身 parents、离婚、再婚、同性恋 parents、法定监护人)。
当结构可以共享时,您可以在结构中放置一个引用计数,只有当它减少到零时才释放。
我嵌套了四层不同的结构。代码如下:
typedef struct System system;
typedef struct College college;
typedef struct Student student;
typedef struct Family family;
#define MAX_COLLEGES 10
#define MAX_NAME_LEN 32
#define MAX_STUDENTS 10
struct System {
college *Colleges[MAX_COLLEGES];
};
struct College {
char name[MAX_NAME_LEN];
student *Students[MAX_STUDENTS];
};
struct Student {
char name[MAX_NAME_LEN];
int id;
family *fam; //was typo familiy
};
struct Family {
char fatherName[MAX_NAME_LEN];
char motherName[MAX_NAME_LEN];
};
并且我给它们都分配了内存(我不确定是否分配正确),如下:
system *collegeSys = malloc(sizeof(system));
college *colleges = malloc(sizeof(college));
student *students = malloc(sizeof(student));
family *fam = malloc(sizeof(family));
// then the following is initialization
...
...
...
现在,我需要删除 collegeSys
结构以及与之关联的所有内容。所以,我不知道我是否可以只释放第一个 collegeSys
结构而不释放任何其他结构,如下所示:
free(collegeSys);
或者为了 "delete anything associated with it",我必须自下而上释放所有内容,如下所示:
free(fam);
free(students);
free(colleges);
free(collegeSys);
或者为此,我什至必须释放每个结构中包含的所有内容并自下而上释放它们,如下所示:
free (fam -> fatherName);
free (fam -> motherName);
free (fam);
free (students -> name);
free (students -> id);
free (students -> fam);
free (students)
.
. till
.
free (collegeSys -> colleges);
free (collegeSys);
哪一种是释放内存的正确且安全的方法?或者 none 是?
我不太明白指针数组的意义,它可以用指针来完成。
定义:
struct System {
college *Colleges;
};
struct College {
char name[MAX_NAME_LEN];
student *Students;
};
struct Student {
char name[MAX_NAME_LEN];
int id;
familiy *fam;
};
struct Family {
char fatherName[MAX_NAME_LEN];
char motherName[MAX_NAME_LEN];
};
分配和初始化:
system *collegeSys = malloc(sizeof(*collegeSys));
collegeSys->colleges = malloc(MAX_COLLEGES * sizeof(*(collegeSys->colleges)));
collegeSys->colleges->students = malloc(MAX_STUDENTS * sizeof(*(collegeSys->colleges->students)));
collegeSys->colleges->students->fam = malloc(sizeof(*(collegeSys->colleges->students->fam)));
释放:
free(collegeSys->colleges->students->fam);
free(collegeSys->colleges->students);
free(collegeSys->colleges);
free(collegeSys);
更新:
Like I want to have struct student A, B, C, D under a struct college
collegeSys->colleges->students[0] = A;
collegeSys->colleges->students[1] = B;
collegeSys->colleges->students[2] = C;
collegeSys->colleges->students[3] = D;
应该做。
如果您有 student
数组,您可以使用 memcpy
或复制到 loop
。
struct student stud[MAX_STUDENTS] = {...};
memcpy(collegeSys->colleges->students[2], stud, MAX_STUDENTS);
或
for (int i = 0; i< MAX_STUDENTS; i++)
collegeSys->colleges->students[i] = stud[i];
注:
您可以将数组分配给 collegeSys->colleges->students
,在这种情况下您不需要动态内存分配或释放。
// collegeSys->colleges->students = malloc(MAX_STUDENTS * sizeof(*(collegeSys->colleges->students))); //Leaks memory
collegeSys->colleges->students = stud;
//free(collegeSys->colleges->students); //wrong
分配一个结构然后将其中的所有指针设置为 NULL。 例如,要分配你的 College 结构,你需要将所有学生设置为 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 );
}
}
请注意,这假设 没有共享 指针,例如同一个学生在不止一所大学(当实施只为每个学生分配一个结构时),或者当有两个兄弟姐妹共享相同的家庭结构时。 (家庭结构不能很好地模拟家庭,例如单身 parents、离婚、再婚、同性恋 parents、法定监护人)。 当结构可以共享时,您可以在结构中放置一个引用计数,只有当它减少到零时才释放。