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

时间:2012-04-25 17:46:59

标签: c pointers linked-list

我在一本书中找到了这段代码:

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

假设我们传递给函数的参数是指向列表头部的指针,为什么我们不传递对该指针的引用?

如果我们不这样做,我们不是要删除该指针的本地副本吗?那就是我们传递参考指针的原因吧?那么被调用者获得了在函数内部完成的更改吗?

5 个答案:

答案 0 :(得分:5)

  

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

嗯,在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));
}

答案 1 :(得分:5)

将指针传递给指针(不是对指针的引用,因为C根本没有引用)将是一个更好的解决方案,因为您可以在删除后将其清空。正如它当前定义的那样,如果调用者不小心,该函数可能会留下悬空指针。除了这个小问题,这个解决方案是有效的:调用者可以在将NULL传递给DeleteList()后手动将void DeleteList(element **head) { element *next, *deleteMe; deleteMe = *head; while (deleteMe) { next = deleteMe->next; free(deleteMe); deleteMe = next; } *head = NULL; } 手动分配给列表头。

以下是我用指针指针重写的方法:

{{1}}

答案 2 :(得分:2)

@dasblinkenlight的代码可以更紧凑。

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

您无需更改来电者中列表头部的值。

// 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;