2013-03-03 73 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