几天前,我问了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
等)来避免出现段错误吗?
很抱歉写这么长的文字。感谢您的耐心等候。