0

我试图编写一个简单的函数来释放动态分配的内存

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

使用主函数将值赋予列表,并且在此特定函数中,即使在释放 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

如果你注意到.. 最后两行返回相同的数据值.. 即使我用更大的列表尝试了这个。同样的事情也会发生!最后 2,3 个值(即 head_new->data)按原样返回。我的问题:这是一种错误吗?或者有这样的价值观是正常的?这件事与我有关,因为没有免费的返回类型,那么它如何显示相同的值?请帮助我清除我的疑问。

4

2 回答 2

6
free(head_new);
printf("free returns %p, %d", head_new->link, head_new->data);

导致您的程序具有未定义的行为(UB)。请注意,一旦您调用free了指针,任何取消引用指针的尝试head_new都会导致未定义的行为。
UB 意味着您的程序可以显示任何行为,而不必产生崩溃。简单地说取消引用它是无效的,不应该这样做。

幕后可能会发生什么?

free不会重新初始化已释放的内存,它只是将其标记为可重用。
因此,地址处的内容仍然相同,并且引用指针会为您提供这些内容。但是,这并不重要,因为 UB 发生在您取消引用指针的那一刻。

于 2013-01-24T07:08:16.543 回答
2

该值将一直存在,直到它被其他一些数据覆盖。

当你释放时,唯一发生的事情是内存将被放回空闲池,这样如果其他人要求,就会给你一个。

于 2013-01-24T07:07:36.887 回答