我是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也应该释放其成员的内存。但是为什么行得通呢?释放结构后,如果要访问结构的成员该怎么办?
答案 0 :(得分:9)
成员是结构的一部分。释放结构会释放其所有成员。
但是,在您的示例中,成员只是指针。您正在将指针复制到结构(node->data1 = ...
)中,然后从结构(... = node->data1
)中复制出来,然后释放结构。这些都不会影响指针指向的内存。
在您的示例中,实际的字符串存储在静态内存中(它们是字符串文字)。这意味着它们永远不会被摧毁。只要程序运行,它们就一直存在。这就是为什么打印它们绝对安全。您的代码很好。
最后,访问已释放的内存具有未定义的行为(意味着任何事情都可能发生,包括程序崩溃或看起来正常工作)。如果要访问已释放的结构的成员,只需执行以下操作:
struct elem *p = malloc(sizeof *p);
free(p);
p->data1 = "boom!"; // Undefined behavior!
但是,那将是一个错误,所以……请不要。
答案 1 :(得分:7)
每个 malloc
必须与相应的free
保持平衡。
您的分配node->data1 = "abc";
分配了一个指向只读文字"abc"
的指针,因此这里没有动态内存,因此您不能使用{{1 }}。
在特定情况下,您可以保留指针free
在a
上调用了free
的指针,因为您不必{{1 }}该内存,它从来都不属于struct
。但这通常不起作用:如果您使用free
来设置struct
,则(1)您必须在之前对该指针调用malloc
尝试在node->data1
上调用free
,并且(2)后续free
的引用的行为将是不确定的。