c - 无分支链表删除 C 中的条目
问题描述
在这个 TED 演讲中,Torvalds 提出了一个没有 if 条件的删除入口函数。我尝试在下面的代码中进行模拟,但如果要删除的条目是列表的头部,则它不起作用。1.)为什么这不能专门去除头部?2.) 这种方法不会产生内存泄漏,因为我们从不释放条目吗?
/** a data structure representing a node **/
struct node {
int data;
struct node* next;
};
/** create a new node and return a pointer to it**/
struct node* new_Node(int data)
{
struct node* newP = malloc(sizeof(struct node));
newP-> data = data;
newP-> next = NULL;
return newP;
}
/** function to print out a list**/
void list_print(struct node* head)
{
printf("Begin List Print:\n");
struct node* tmp = malloc(sizeof(struct node));
tmp = head;
while(tmp != NULL ) {
printf("%d\n", tmp->data);
tmp = tmp->next;
}
printf("End List Print\n\n");
}
/** function to delete one node **/
void list_remove_entry(struct node* head, struct node* entry)
{
struct node** indirect = &head;
while((*indirect) != entry) {
indirect = &(*indirect)->next;
}
*indirect = (*indirect)->next;
}
/** the program entry point**/
int main()
{
struct node* head = new_Node(1);
struct node* n1 = new_Node(2);
struct node* n2 = new_Node(3);
head->next = n1;
n1->next = n2;
list_print(head);
list_remove_entry(head, head);
list_print(head);
return 0;
}
解决方案
TED 演讲中的代码不head
作为参数,它是一个全局变量。
结果,当它发生
*indirect = entry->next;
head
如果要删除的条目等于,它将修改变量head
,因为while
循环立即停止并且indirect
仍然包含&head
。
当您创建参数时,这并不相同head
,因为现在您只是修改局部变量,而不是调用者的变量。请参阅使用函数更改指针包含的地址,了解如何重新设计函数来解决这个问题(它也在@tadman 的答案中)。
在回答您的第二个问题时,是的,这会造成内存泄漏。Linus 的示例只是为了说明编写此函数的两种方法的一个特定方面,因此他省略了与该差异无关的所有内容。您可以通过将作业替换为以下内容来解决此问题:
(*indirect)->next = (*indirect)->next->next;
free(*indirect);
请注意,他还遗漏了错误检查。他的代码假定会找到该条目,因此他*indirect == NULL
在取消引用之前从不检查(并且我上面的分配不检查双重间接)。
这不是一堂编码课,它只是一个需要放在幻灯片上的简单示例。
推荐阅读
- node.js - 节点查询字符串库中的未知选项
- python - waiter.acquire() 在线程中做了什么?
- redux - 中间件中的调度导致错误类型的操作
- javascript - 删除事件侦听器不起作用
- python - (垂直)滚动视图包含另一个(水平)滚动视图 - Kivy
- vue.js - Vue JS 如何从一个数据中取一个值到另一个数据?
- javascript - ShellExecute 权限被拒绝 SCRIPT70,IE11 windows 10
- go - 如何对模板中的结构切片中包含的切片进行范围划分?
- google-cloud-platform - GCP - 如何为虚拟机部署添加标签
- runtime - GPRbuild:聚合项目中忽略的“运行时”属性