我试图编写一个简单的函数来释放动态分配的内存
typedef struct list{
int data;
struct list * link;
} list;
list * head = NULL;
void release(list * head_new){
list * dummy = NULL;
while(head_new != NULL){
dummy = head_new->link;
printf("before freeing %p, %d", head_new->link, head_new->data);
free(head_new);
printf("free returns %p, %d", head_new->link, head_new->data);
head_new = dummy
}
}
Run Code Online (Sandbox Code Playgroud)
使用主函数值被赋予列表,并且即使在释放head_new节点之后,在该特定函数中也会打印一些值
1
12
1
123
1 12 1 123 before freeing 00622A40, 1
free returns 006200C4, 6433408
before freeing 00622A60, 12
free returns 006200C4, 6434048
before freeing 00622A70, 1
free returns 006200C4, 6433344
before freeing 00000000, 123
free returns 00000000, 123
Run Code Online (Sandbox Code Playgroud)
如果你注意到..最后两行返回相同的数据值..即使我尝试使用更大的列表.同样的事情发生了!最后的2,3个值(即head_new-> data)按原样返回.我的问题:这是一种错误吗?或者这样的价值观是正常的吗?这件事关心我,因为没有返回类型的免费,那么它如何显示相同的价值?请帮我清除疑虑.
free(head_new);
printf("free returns %p, %d", head_new->link, head_new->data);
Run Code Online (Sandbox Code Playgroud)
导致程序具有未定义的行为(UB).请注意,一旦调用free指针,任何取消引用指针的尝试head_new都会导致未定义的行为.
UB意味着您的程序可以显示任何行为,它不必产生崩溃.简单地说,取消引用它是无效的,不应该这样做.
幕后可能发生什么?
free没有重新初始化已释放的内存,它只是标记它可以重用.
因此地址中的内容仍然相同,并且引用指针会为您提供这些内容.但是,这并不重要,因为UB发生在您取消引用指针的那一刻.