由malloc和自由行为混淆

时间:2013-03-03 12:00:23

标签: c malloc free

我对free()关于C中数据结构的使用感到困惑。

如果我有以下数据结构:

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;
}

4 个答案:

答案 0 :(得分:5)

me->name = "Fotis";

/* ... */

free(me->name);

规则是:

1 malloc = 1 free

您未malloc使用me->name,因此您无需free

BTW,me->name应为const char *类型。

答案 1 :(得分:1)

当你这样做时

    me->name = "Fotis";

name指针不是由malloc分配的,它指向一个堆栈变量,它在编译时存储在二进制文件的strings表中,因此你无法释放它。

经验法则是:只释放你所拥有的物品。

但您无法更新此只读字符串。

如果你做了类似的事情:

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

由于strdup执行malloc(请参阅手册),您必须释放它,并且可以在创建后更新字符串。

答案 2 :(得分:1)

是的,如果你分配它们,你必须释放结构内指针的所有内存。

另外,请确保在释放结构之前释放成员。

一种简单的记忆方式是按照你已经分配的相反顺序释放它们。

答案 3 :(得分:1)

问题是你实际上没有在你的结构中使用mall *来表示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'ed。