2013-03-03 68 views
5

困惑我很困惑與free()關於數據結構C.使用由malloc和free行爲

如果我有以下數據結構:

struct Person { 
    char *name; 
    int age; 
    float weight; 
    float height; 
}; 

我的內存分配通過結構malloc(),同樣:struct Person *me = malloc(sizeof(struct Person));

我(結束程序前右),但以我的結構完成後,我繼續釋放內存分配,像這樣:

free(person_pointer->name); 
free(person_pointer); 

釋放內存的name指針指向是必要的,據我所知,因爲如果我只免費person_pointer我只釋放已分配存儲數據結構的存儲器及其成員但不是記憶這是由結構的成員指針指向的。

但是我的執行valgrind似乎暗示第一個free()是無效的。

所以我的問題歸結爲:當我釋放一個結構體通過指針佔用的內存時,我應該搶先釋放成員指針指向的內存嗎?

編輯:這是我的全部代碼:

#include <stdio.h> 
#include <stdlib.h> 

struct Person { 
    char *name; 
    int age; 
    float weight; 
    float height; 
}; 

int main(int argc, char **argv) 
{ 
    struct Person *me = malloc(sizeof(struct Person)); 
    me->name = "Fotis"; 
    me->age = 20; 
    me->height = 1.75; 
    me->weight = 75; 

    printf("My name is %s and I am %d years old.\n", me->name, me->age); 
    printf("I am %f meters tall and I weight %f kgs\n", me->height, me->weight); 

    free(me->name); 
    free(me); 

    return 0; 
} 
+0

@Mat我做malloc()。我將編輯這個問題來澄清這一點。 – NlightNFotis 2013-03-03 12:02:33

+0

@Mat剛用我的分配方法更新了這個問題。如果您需要更多信息,我可以發佈我的整個代碼,這是一個相當小的程序,但是從現在開始,爲了清晰起見,我不會這麼做。 – NlightNFotis 2013-03-03 12:05:31

+1

用於完整測試用例的+1,使用Valgrind等。 – 2013-03-03 12:12:03

回答

5
me->name = "Fotis"; 

/* ... */ 

free(me->name); 

的規則是:

1 malloc = 1 free 

你們沒有me->name使用malloc,所以你不必free它。

BTW,me->name應該是const char *類型。

1

當你

me->name = "Fotis"; 

name指針沒有被malloc的alloced,它指向的是存儲在編譯的時候你的二進制文件的字符串表中的堆棧變量,因此你不能免費它。

經驗法則是:只有免費的你有malloced。

儘管你不能更新這個只讀字符串。

如果你不喜歡的東西:

me->name = strdup("Fotis"); 

的strdup以來做一個malloc(請參閱手冊),你必須釋放它,你可以更新其創建之後的字符串。

1

是的,你必須釋放結構中指針的所有內存,如果你分配它們。

還要確保在釋放結構之前釋放成員。

一個簡單的記住方法是按照您分配的相反順序釋放它們。

1

問題是你實際上沒有在你的結構中使用char *名稱。

struct Person *me = malloc(sizeof(struct Person)); 
me->name = strdup("Fotis"); 
... 
free(me->name); 
free(me); 
return (0); 

當你寫這個

me->name = "Fotis"; 

其實你不malloc的,指針的名稱指向const char *類型的堆棧變量,至極不是malloc分配。

+3

'strdup'不是標準庫函數。可能最好不要推薦它... – 2013-03-03 12:14:59

+0

字符串文字是靜態存儲的,而不是在堆棧中。指向它的指針在程序中任何地方的任何函數中都是有效的。 – teppic 2013-03-03 15:49:15