2014-03-13 19 views
1

我想在代码片段中找到与内存分配相关的两个错误。在讲座中说,第一个错误是返回,第二个不释放内存。我不明白为什么第一个是错误。第二个我不确定,但有一个好主意,为什么。C语言中的内存管理错误。为什么这些错误?

对于第一个错误,class是一个学生数组,函数getClassInfo返回一个指向这个数组的指针,对我来说似乎很好。

我想我明白为什么内存应该free'd虽然。在for循环的每次迭代中,thisStudent被malloc分配内存,然后class [i]被分配给thisStudent的值。在每一次迭代中,这个学生都会重新分配一个新的内存块,但最后一个永远不会释放。

任何澄清,为什么第一个错误是一个错误将不胜感激! 谢谢 克里斯 -

#include <stdio.h> 
#define CLASS_SIZE 500 

typedef struct student { 
    int studentNr; 
    char grade; 
} student; 

student * getClassInfo(void){ 
    int i; 
    student class[CLASS_SIZE]; 

for(i = 0; i < CLASS_SIZE; i++){ 
    student * thisStudent = (student*) malloc(sizeof(student)); 
     if(thisStudent == NULL) return(NULL); 
     scanf("%d %c", &(thisStudent->studentNr),&(thisStudent->grade)); 

     class[i] = *thisStudent; 
     } 
    return class; 
} 

我得到一个警告说,它的返回一个局部变量的地址,编译时,但如何是关系到内存分配错误?

+0

由于数组是本地的函数,它不再存在于函数出口,所以你正在返回的指针指向一个现在已经死亡的。这可能是关于C最常见的问题,我很惊讶你没有找到答案。 –

+0

我同意我在问之前应该多研究一下,有时候我似乎只是试图提出一个好问题就能更好地发现问题。感谢您通过Matteo的帮助! – kiwicomb123

+0

顺便说一下,请注意'class'是C++中的一个关键字,如果您尝试使用C++编译器编译此代码,将导致编译错误。只要你坚持使用C,它就不是问题,但是因为*大多数有效的C代码也是有效的C++,并且有时可以将它编译为C++,所以避免使用C++关键字可能是谨慎的作为C程序中的标识符。考虑命名你的数组'学生',而不是。 – Wyzard

回答

2

classgetClassInfo()函数中的局部变量,这意味着函数返回时它不再存在。 return class;语句返回一个指针,该指针在调用方接收它时不再有效。

您应该声明classstudent*并与malloc()动态分配,就像您为学生自己做的一样。它将它分配到堆上,所以它会一直存在,直到你明确地将它存储为free()。你会想要做malloc(sizeof(student) * CLASS_SIZE)为所有的学生结构分配连续的空间。

你说得对,没有释放student在循环中分配的结构是一个错误(特别是内存泄漏)。你根本不需要动态分配学生;您只需将学号和成绩存入class[i].studentNrclass[i].grade即可。