gpt4 book ai didi

c - 对函数内部的自由指针有点困惑

转载 作者:太空宇宙 更新时间:2023-11-04 03:40:19 26 4
gpt4 key购买 nike

几周前,我了解了如何在函数内部分配和释放指针的正确方法,如示例 linkedList 所示:

typedef struct _node {
void *data;
struct _node *next;
} Node;

typedef struct _linkedList {
Node *head;
Node *tail;
Node *current;
} LinkedList;

在我看来,销毁队列的正确方法是使用获取指向我要删除的节点的指针的函数:

void destroy (Node ** node) 

或者在更真实的示例中,指向要删除的指针和指向列表的指针。

void destroy (LinkedList * list, Node ** node) 

但现在我正在阅读“Understanding C pointers”一书,我遇到了问题,因为在第 6 章指向结构的指针中有函数 destroyList 的示例:

void delete(LinkedList *list, Node *node) {
if (node == list->head) {
if (list->head->next == NULL) {
list->head = list->tail = NULL;
} else {
list->head = list->head->next;
}
} else {
Node *tmp = list->head;
while (tmp != NULL && tmp->next != node) {
tmp = tmp->next;
}
if (tmp != NULL) {
tmp->next = node->next;
}
}
free(node); //free on pointer copy value not pointer
}

所以在这个例子中,作者在按值传递的指针上自由运行,所以在我看来这不应该起作用。但是我查看了勘误表,没有关于这个例子的注释。

在这种情况下,我理解 List 是使用正确列表实例的函数参数,但应该是:

free(list->head) ; //It should work?

然后还为分配的列表释放内存。

我说的对吗?因为看了这个例子,我觉得我对这个主题的理解有问题。

我还去了 Linux 手册页,我看到了免费的原型(prototype):

 void free(void *ptr);    // http://linux.die.net/man/3/free

那么,为什么每个人都告诉您在要释放内存时将指针传递给指针,但在标准库中,相同的自由函数将指针作为参数而不是指向指针的指针,它如何正确工作?

最佳答案

正如您正确陈述的那样,free( void *p ) 释放了 p 指向的内存,但是由于地址是按值传递的,因此对于调用者而言它将保持不变。因此你可能会遇到这样的问题:

int *p = malloc( sizeof *p );

*p = 1;
free( p );
...

if( p )
*p = 2; // Undefined Behaviour!!! although p is free()'d it's still != NULL

所以你会经常发现

free( p );
p = NULL;

尽管如此,在我看来,编写一个类似 free() 的函数是可以的,只要函数的描述清楚地表明指针不能 之后使用(无论可能是什么类型的指针)。但是,当然你可以自由地用双指针定义函数,并将你有 free()'d 的所有内容设置为 NULL ,就像这个非常简单的例子一样:

void myfree( void **pp )
{
free( *p );
*p = NULL;
}

...
int *p = malloc( sizeof *p );
...
myfree( &p );
// now p == NULL

关于c - 对函数内部的自由指针有点困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29218271/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com