如果我释放链表的头节点,它是否会删除头节点,其他节点仍然在内存中,或者它将释放整个列表以及如何?
答案 0 :(得分:5)
您的链接列表应该是:
head
+---+ +---+ +---+
| 1 |--->| 2 |--->| 3 |---+
+---+ +---+ +---+ |
null
head
节点仅保留第一个节点的地址,如果执行free(head)
,则它将释放第一个节点的内存,其值为1
和其他-nodes仍然在内存中并且有效访问它们,但是你应该首先保存节点2
的地址,以访问链表(否则你的代码中会有内存泄漏)。
喜欢:
new_head = head->next;
free(head);
一旦你释放/释放()一个内存,它的未定义行为就不能访问(地址变得无效)。
来自评论:
是的,你需要为链表中的所有节点提供一个循环到free()内存,做这样的事情:
while(head){ // while head not null
new_head = head->next; // first save address of next
free(head); // free first node
head = new_head; // set head to next node, not yet free
}
答案 1 :(得分:1)
释放头节点只会释放分配给头节点的内存。将保留其他列表节点。然后,您必须指向列表的下一个成员。例如,考虑以下单个链表,
A - > B - > C - > D - >空
释放头节点A并将头部移动到节点B后,链表将如下所示
B - > C - > D - >空
答案 2 :(得分:1)
释放列表的头节点只释放该节点,不列表的其余部分。
这是数组和链表之间的主要区别 - 内存是分开的。 这是一个例子:
struct testnode {
int a;
int b;
struct testnode * next;
};
在数组中,内存可能如下所示:
struct testnode test[3];
0x............0000 &test[0] // on a typical computer
0x............0020 &test[1]
0x............0040 &test[2]
注意数组中的元素是如何彼此相邻排列的? 释放测试将释放并且随后的连续内存,只需要一次调用即可释放所有内存。
在链接列表中,内存可能如下所示:
struct testnode * head;
// after insertions
0x............0000 head
0x............634f head->next
0x............114d head->next->next
注意内存是如何排序的(虽然它可能并不总是 乱序)。
释放head
只会释放head
节点,而其他内存不会受到影响。
答案 3 :(得分:0)
不,当你释放链表的头节点时,你只标记它用作“免费使用”的内存。因此,内存中的其他节点仍将标记为“正在使用中”。
从技术上讲,您仍然可以使用释放的内存,但它是未定义的行为,因此无法保证数据(包括指针)仍然可以正确使用。
如果要从内存中删除所有节点,则应该递归执行(从next
指针的角度来看)。