如何正确、安全地释放()C中嵌套结构使用的所有内存?

如何正确、安全地释放()C中嵌套结构使用的所有内存?,c,memory-management,struct,linked-list,c99,C,Memory Management,Struct,Linked List,C99,我有四个不同的嵌套结构层。代码如下: 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 *Co

我有四个不同的嵌套结构层。代码如下:

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
...
...
...
我将内存分配给了所有的内存(我不确定是否正确分配了所有内存),如下所示:

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
struct,如下所示:

free(collegeSys);
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);
或者为了“删除与之相关的任何内容”,我必须自下而上释放所有内容,如下所示:

free(collegeSys);
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);
或者为此,我甚至必须释放每个结构中包含的任何内容,并自下而上地释放它们,如下所示:

free(collegeSys);
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);

哪种方法是释放内存的正确且安全的方法?或者它们都不是?

我真的不理解拥有指针数组的意义,它可以通过指针来完成

定义:

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);
释放:

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

更新:

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);
就像我想让struct学院的学生A,B,C,D一样

我应该这样做

如果你有
student
s数组,你可以使用
memcpy
或在
循环中复制

struct student stud[MAX_STUDENTS] = {...};

memcpy(collegeSys->colleges->students[2], stud, MAX_STUDENTS);


分配结构时,将其中的所有指针设置为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;
}
struct College*CollegeAlloc(字符名[MAX\u name\u LEN]){
struct College*College=malloc(sizeof(struct College));
国际单项体育联合会(学院){
对于(int i=0;i学生[i]=NULL;
memcpy(学院->名称、名称、最大名称);
}
返回学院;
}
或者,您可以在每个数组的结构中添加一个count字段,以计算实际使用的数组元素数

如果在不使用时将数组元素设置为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 );
    }
}
void FamilyFree(结构族*fam){
免费(fam);
}
无效StudentFree(结构学生*Student){
如果(学生){
家庭自由(学生->家庭);
免费(学生);
}
}
无效学院免费(结构学院*学院){
国际单项体育联合会(学院){
对于(int i=0;i学生[i]);
免费(大学);
}
}
void SystemFree(结构系统*sys){
if(sys){
对于(int i=0;iColleges[i]);
免费(sys);
}
}
注意:这假设指针不共享,例如同一学生在多所大学就读(当实施只为每个学生分配了一个结构时),或者当两个兄弟姐妹共享同一家庭结构时。(家庭结构不能很好地模拟家庭,例如单亲、离婚、再婚、同性恋父母、法定监护人)。
当结构可以共享时,您可以在结构中放置引用计数,只有当引用计数减少到零时,您才可以释放引用计数。

您希望10所学院作为系统的一部分吗。当前的结构分配一个大学指针数组,相当于一个二维数组array@RishikeshRaje是 啊10所学院是系统的一部分,10名学生是每个学院的一部分。所以,它不应该是2D数组,这意味着一个指针就足够了(实际上,为了这个目的,我只需要一个1D数组)?谢谢。虽然我不确定自己是否正确,但我尝试通过一系列指针在学院结构下存储多个学生信息,这与在系统下处理学院的做法是一样的。只需一个指针,就可以在一个学院下获得多个学生的信息,这也行吗?就像我想在A
struct college
下有
struct student A、B、C、D
。如果我想有更多的学生,我是否要增加
MAX_STUDENTS
的大小来分配内存?@SpittyDog是的。你好,非常感谢。有几个问题:1)如果我们只定义了一个学生结构指针,而不是大学结构中的指针数组,那么我们是否可以使用
college->Students[i]=NULL
?e、 我想我们不能这样做。我在Xcode上尝试了这个,它在分配给。。。不兼容的类型“void*”。2) 当我们将内存分配给结构时,是否必须将其中的所有指针都设置为NULL?e、 g.只这样做可以吗:
struct system*collegeSys=malloc(sizeof(struct system))3)如果我们这样做,我们是否只需要为其父结构中定义的子结构设置空值,而不需要为嵌套在其中的所有内容设置空值?e、 g.在第一个代码块中,您只为student结构置零,而没有为student结构中嵌套的族结构置零。所以,当我们将内存分配给学生结构时,而不是当我们将内存分配给大学结构时,空家庭结构是我们应该做的工作,是吗?1。不可以。学生需要是struct Student*的数组类型(或等效的typedef)。或者,类型可以是struct Student**,并分配一个用calloc()分配的动态数组。然后使用index[]表示法。@SpittyDog 2。如果不初始化,则内容可能是随机的无意义值。如果您有其他方法来跟踪初始化的内容和未初始化的内容,那么您就不必进行初始化。这种方法需要额外的数据和编程维护。@Spitydog 3。尚未分配学生结构。所以你不能对学生结构做任何事情。i、 e如果学生数组为空,则创建空学生名额。您最终会想要分配一个student结构,初始化它,并将其放入College结构中Students数组的一个(未使用的)元素中。这将是一个“注册”功能。