Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中删除整个链表-为什么不使用引用指针?_C_Pointers_Linked List - Fatal编程技术网

在C中删除整个链表-为什么不使用引用指针?

在C中删除整个链表-为什么不使用引用指针?,c,pointers,linked-list,C,Pointers,Linked List,我在一本书中发现了这段代码: void DeleteList(element *head) { element *next, *deleteMe; deleteMe = head; while (deleteMe) { next = deleteMe->next; free(deleteMe); deleteMe = next; } } 假设传递给函数的参数是指向列表头的指针,为什么不传递指向该指针的引用 如果我们不这样做,我们不是要删除该指针的本

我在一本书中发现了这段代码:

void DeleteList(element *head)
{
  element *next, *deleteMe;
  deleteMe = head;
  while (deleteMe) {
    next = deleteMe->next;
    free(deleteMe);
    deleteMe = next;
  }
}
假设传递给函数的参数是指向列表头的指针,为什么不传递指向该指针的引用


如果我们不这样做,我们不是要删除该指针的本地副本吗?这就是为什么我们传递引用指针,对吗?因此被调用方可以得到函数内部所做的更改?

当调用
free
时,指针本身不会更改,因此不需要通过引用传递它

如果我们不这样做,我们不是要删除该指针的本地副本吗

在C中没有引用,但我假设你指的是指向指针的指针,答案是否定的

您正在释放堆上指针指向的内存,而不是指针本身。您没有改变指针,因此可以复制。不管它是不是副本,它们都指向同一个地方

您将这与为传递给函数的变量指定一个全新的值相混淆,在这种情况下,您需要使用指向指针的指针。例如:

// only changes the local copy
void init(some_type *foo) {
    foo = malloc(sizeof(some_type));
}

// initializes the value at *foo for the caller to see
void init(some_type **foo) {
    *foo = malloc(sizeof(some_type));
}

您不需要更改调用者中列表头的值

// caller
DeleteList(head);
// head points to an invalid place (the place where the list used to be)
// for convenience sake, reset to NULL
head = NULL;

将指针传递给指针(而不是指针的引用,因为C根本没有引用)将是一个更好的解决方案,因为删除后您可以将其清空。按照目前的定义,如果调用方不小心,函数可能会留下悬空指针。除了这个小问题之外,这个解决方案是有效的:调用方在将列表头传递给
DeleteList()
之后,始终可以手动将其分配给
NULL

下面是我将如何使用指向指针的指针重写它:

void DeleteList(element **head) {
    element *next, *deleteMe;
    deleteMe = *head;
    while (deleteMe) {
        next = deleteMe->next;
        free(deleteMe);
        deleteMe = next;
    }
    *head = NULL;
}

@dasblinkenlight中的代码可以更加紧凑

void DeleteList(element **head) {
    element *deleteMe;
    while ((deleteMe = *head)) {
        *head = deleteMe->next;
        free(deleteMe);
    }
}

我们删除该指针的本地副本指向的块。