如何在C中将内存分配给多嵌套结构?

时间:2019-07-10 09:42:51

标签: c pointers memory-management struct memory-leaks

几天前,我问了question。我重复了上一个问题的答案中给出的90%的代码。但是,当我使用Valgrind进行memcheck时,它告诉我内存泄漏。但是我不认为是10%的差异导致内存泄漏。除了内存泄漏问题,我还有其他几个问题。

我以前的帖子的简短摘要: 我有一个多嵌套结构。我需要为其正确分配内存,并在以后释放内存。整个结构的结构应如下所示:

                          College Sys
           |           |           |      ...      |
        ColleA       ColleB      ColleC   ...     ColleX
    |  |  |  |    |  |  |  |   |  |  |  |  ...  |  |  |  |
   sA sB sC  sD  sA sB sC  sD sA sB sC  sD ... sA sB sC  sD
    |  |  |  |    |  |  |  |   |  |  |  |  ...  |  |  |  | 
   fam fam ...
// Colle is short for college
// s is short for stu (which is short for student)

可以有任意数量的大学和学生,这可由#define MAX_NUM _num_控制。


按照前面的答案,我应该按照“从最内到最内”的顺序分配内存,并从“最内到最外”释放内存。我基本上了解了模式背后的逻辑。以下问题是对它的扩展。

1)

CollegeSys -> Colle = malloc(sizeof(*(CollegeSys -> Colle)) * MAX_NUM);
CollegeSys -> Colle -> stu = malloc(sizeof(*(CollegeSys -> Colle -> stu)) * MAX_NUM);
CollegeSys -> Colle -> stu -> fam = malloc(sizeof(*(CollegeSys -> Colle -> stu -> fam)));

意味着“在大学体系下有MAX_NUM所大学,每所大学都有MAX_NUM个学生,每个大学都有一个家庭”?

1.a)如果是,我是否仍然需要 for循环来初始化此庞大结构中包含的每个单个值? 例如,可能正确的方法:

for (int i = 0; i < MAX_NUM; i++) {
    strcpy(CollegeSys -> Colle[i].name, "collestr");
    for (int n = 0; n < MAX_NUM; n++) {
        strcpy(system -> Colle[i].stu[n].name, "stustr");
        ...
    }
}

可能不正确的方法:

strcpy(CollegeSys -> Colle -> name, "collestr");
strcpy(CollegeSys -> Colle -> stu -> name, "stustr");

我尝试了“可能不正确的方式”。没有语法错误,但是只会初始化CollegeSys -> Colle[0].name... -> stu[0].name。因此,如果要初始化每个属性,第二种方法很可能是不正确的。

2)如果我将整个过程模块化,请将该过程分为几个函数,这些函数返回相应的结构指针-newSystem(void)newCollege(void)newStudent(void)(自变量不一定是空的;我们可能还会将str作为name传递给函数;此外,可能会有一系列的addStu()等,以将返回的指针分配给{{ 1}})。当我在CollegeSys中创建一个新的CollegeSys时,一次又一次地在newSystem()中为每个嵌套结构分配内存是正确的吗?

2.a)如果我将内存分配给newSystem()中结构的所有部分,那么到目前为止我可能想到的可能结果是内存泄漏。由于在创建系统时已为所有部分分配了内存,因此不可避免地必须创建一个新的struct指针,并在其他两个函数中为其分配足够的内存。例如,

newSystem()

如果是这样,我们实际上至少两次将相同数量的内存分配给一个实例-一个在struct Student* newStudent(void) { struct Student* newStu = malloc(sizeof(struct Student)); newStu -> fam = malloc(sizeof(*(newStu -> fam))); // I'm not sure if I'm supposed to also allocate memoty to fam struct ... return newStu; } 中,另一个在newSystem(void)中。如果到目前为止我是正确的,那肯定是内存泄漏。并且我们分配给newStudent(void)中的指针newStu的内存永远都不会被释放(我认为是)。那么,当我们将整个内存分配过程分为几个小步骤时,将内存分配给整个结构的正确方法是什么?

3)将内存分配给嵌套在结构中的结构时,是否必须使用newStudent(void)?我们可以直接指定它的类型吗?例如,这样做

sizeof(*(layer1 -> layer2 -> ...))

4)看来,即使我们为指针分配了一定数量的内存,我们仍然无法防止segfault。例如,我们编写代码

CollegeSys -> Colle = malloc(sizeof(struct College) * MAX_NUM);
// instead of 
// CollegeSys -> Colle = malloc(sizeof(*(CollegeSys -> Colle)) * MAX_NUM);

我们仍然可以调用// this is not completely correct C code, just to show what I mean struct* ptr = malloc(sizeof(struct type) * 3); ptr[3],依此类推,编译器将打印出废话。有时,编译器可能会抛出错误,但有时可能不会。因此,从本质上讲,我们不能依靠ptr[4](或malloc等)来避免出现段错误吗?

很抱歉写这么长的文字。感谢您的耐心等候。

0 个答案:

没有答案