在C中释放结构是否也会删除其成员?

在C中释放结构是否也会删除其成员?,c,malloc,free,C,Malloc,Free,我是C语言的新手,我有一个关于内存分配的问题。因此,我尝试了下面的代码,它将释放结构elem1 struct elem{ char *data1; char *data2; }; int main() { struct elem *elem1 = malloc(sizeof(struct elem)); elem1->data1 = "abc"; elem1->data2 = "def"; char *a = elem1->

我是C语言的新手,我有一个关于内存分配的问题。因此,我尝试了下面的代码,它将释放结构elem1

struct elem{

    char *data1;
    char *data2;

};

int main()
{

    struct elem *elem1 = malloc(sizeof(struct elem));
    elem1->data1 = "abc";
    elem1->data2 = "def";
    char *a = elem1->data1;
    char *b = elem1->data2;
    free(elem1);

    printf("%s\n%s\n",a,b);
    return 0;
}
代码编译得很好,并且返回

abc 
def
我预料它会失败,因为free也应该释放其成员的内存。但是为什么它会起作用呢?如果我想在释放结构后访问结构的成员,该怎么办?

每个
malloc
都必须与相应的
free
平衡

您的作业
节点->数据1=“abc”
将指针指定给只读文本“abc”,因此此处没有动态内存,因此您不能使用
空闲


在您的特定情况下,您可以在调用
struct
上的
free
后保留该指针
a
,因为您不必
释放该内存,而且它从来都不属于
struct
。但这通常不起作用:如果您使用
malloc
设置
node->data1
,那么(1)在尝试调用
struct
上的
free
之前,您必须在该指针上调用
free
,以及(2)
节点->数据1的后续遵从行为将是未定义的。

成员是结构的一部分。释放结构将释放其所有成员

然而,在您的示例中,成员只是指针。将指针复制到结构中(
节点->数据1=…
),然后从结构中复制出来(
..=节点->数据1
),然后释放结构。所有这些都不会影响指针指向的内存

在您的示例中,实际字符串存储在静态内存中(它们是字符串文本)。这意味着它们从未被摧毁;只要程序在运行,它们就会一直存在。这就是为什么打印它们是完全安全的。你的代码很好

最后,访问释放的内存有未定义的行为(意味着任何事情都可能发生,包括程序崩溃或看起来工作正常)。如果要访问已释放的结构的成员,只需执行以下操作:

struct elem *p = malloc(sizeof *p);
free(p);
p->data1 = "boom!";  // Undefined behavior!

然而,这将是一个错误,所以。。。请不要这样做。

“因此你不能使用免费的”—事实上,
free
不“递归”是件好事。指针和它指向的数据之间有区别,理解它至关重要。释放存储指针的内存(如结构实例的成员内存)对指针指向的数据没有影响。请注意,调用
free
后,代码不会访问任何成员!您只能访问
a
b
,其中包含
自由
之前的成员值副本。这是完全有效的代码。您正在分配到
elem1
中,然后使用
节点
。我想你想在整个过程中使用
elem1
。@选民:这个问题写得很好,编译、运行得很好,OP花了时间记录了实际和预期的行为,而不是“这是ub克服它”之类的问题。因此我投了赞成票(并回答)。@pmg是的,对不起,这是个错误。我已经编辑好了。非常感谢,我现在明白了。