首页 > 解决方案 > 链表删除失败

问题描述

我有一个这样定义的链表

typedef struct Elem Elem;

struct Elem {
    int val;
    Elem *next;
};

我首先写了两个列表删除功能:

void free_list(Elem** head) {
        if (!*head)
            return;
        if (!(*head)->next) {
            free(*head);
            *head = 0;
            return;
        }
        free_head(&((*head)->next));
    
}

第二个

void free_list(Elem** head) {
    while (*head) {
        Elem *tmp = *head;
        head = &((*head)->next);
        free(tmp);
    }
}

所以问题是这两个函数在mac os上没有问题,而第二个在ubuntu上不起作用,实际上当我执行它时出现这个错误

free(): double free detected in tcache 2
Aborted (core dump)

所以我想第二个是错误的,但我没有看到错误

标签: clinked-listfreesingly-linked-listfunction-definition

解决方案


这两个函数都不正确。

第一个功能

void free_head(Elem** head) {
        if (!*head)
            return;
        if (!(*head)->next) {
            free(*head);
            *head = 0;
            return;
        }
        free_head(&((*head)->next));
    
}

仅删除列表中的最后一个节点,因为删除节点仅在此 if 语句中发生

        if (!(*head)->next) {
            free(*head);
            *head = 0;
            return;
        }

第二个函数是错误的,因为它没有将指向头节点的指针设置为 NULL,而且( *head )->next在删除包含该数据成员的节点时,它为指针头分配了数据成员的地址。所以该函数具有未定义的行为。

void free_head(Elem** head) {
    while (*head) {
        Elem *tmp = *head;
        head = &((*head)->next);
        free(tmp);
    }
}

该函数可以通过以下方式定义

void free_head( Elem **head ) 
{
    while ( *head ) 
    {
        Elem *tmp = *head;
        *head = (*head)->next;
        free( tmp );
    }
}

递归函数看起来像

void free_head( Elem **head ) 
{
    if ( *head )
    {
        Elem *tmp = *head;
        *head = ( *head )->next;
        free( tmp );
        free_head( head );
    }
}

推荐阅读