2014-03-13 21 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即可。