为什么在单链表中这样使用 free ?

Why using free like this in singly linked list?

typedef struct ListNode{
    char data[4];
    struct ListNode* link;
} listNode;

typedef struct{
    listNode* head;
}linkedList_h;


void freeLinkedList_h(linkedList_h* L){
    listNode *p;
    while(L->head!=NULL){
        p=L->head;
        L->head=L->head->link;
        free(p);
        p=NULL;
    }
}

这是我教科书的示例代码。在freeLinkedList_h中,为什么我们使用“p=NULL”?

如果 p 未设置为 NULL,程序将更容易出现释放后使用错误。 这将更多地依赖于内存分配以及系统保护的具体实现。

通过将指针设置为 NULL,程序更容易发生硬崩溃,在许多情况下,这比访问释放的内存更可取。对于自定义内存分配器,这可能更是如此,因为内存调试器可能并不总是能发现问题,具体取决于自定义内存实现。

对于使用默认 malloc 和朋友的普通程序,这是一个好的内存调试器无法捕捉到的。 但在某些情况下,“清理”不再需要的已用内存肯定是个好习惯。

假设在您的示例中,无论出于何种原因,另一个指针引用了链表节点,并且它试图访问例如next 成员,它不能再意外地工作了。

但如果这确实是作者的意图,他们应该已经澄清并且可能还首先执行了 memset(p, 0, sizeof *p);。因此我倾向于说这不一定是好的做法。

我宁愿推荐使用内存调试器来捕获讨厌的错误,或者只在调试版本中添加额外的指令。