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

Does freeing structures in C also delete its members?

我对 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 也应该释放其成员的内存。但它为什么有效?以及free结构后想访问结构成员怎么办?

每个 malloc 必须与相应的free.

平衡

你的赋值node->data1 = "abc";分配了一个指向只读文字"abc"的指针,所以这里没有动态内存,因此你不能使用 free.

在您的 特定 案例中,您可以保留在 struct 上调用 free 的指针 a,因为您没有必须 free 那段记忆,它从来不属于 struct。但这通常不起作用:如果您使用 malloc 设置 node->data1 那么 (1) 您必须在该指针 之前 [=36] 调用 free =] 您尝试在 struct 上调用 free,并且 (2) node->data1 的后续遵从行为将是未定义的。

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

但是,在您的示例中,成员只是指针。您正在将指针复制到结构中 (node->data1 = ...),然后从结构中复制出来 (... = node->data1),然后释放结构。 None 这会影响指针指向的内存。

在您的示例中,实际字符串存储在静态内存中(它们是字符串文字)。这意味着它们永远不会被摧毁;只要程序是 运行,它们就会存在。这就是为什么打印它们是绝对安全的。你的代码没问题。

最后,访问释放的内存具有未定义的行为(意味着任何事情都可能发生,包括程序崩溃或看似正常工作)。如果您想访问已释放的结构的成员,只需这样做:

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

但是,那将是一个错误,所以...请不要这样做。