无法使用c中的循环链表中的条件删除节点

Can't delete a node using a condition in circular linked list in c

我有一个如下的循环链表,它保存了待处理数据的状态。 status 用于决定从列表中删除,可以是开头、中间或结尾。该列表有时甚至可能根本没有任何数据,或者可能有多个节点要删除。

struct data
{
    bool status;
    char other_info[20];
    struct data *next;
};

我尝试了以下代码

struct data* delete_nodes(struct data *head)
{
    struct data* first = NULL, *prev = NULL, *temp = NULL;
    first = head;
    temp = head;
    prev = head;
    do
    {
        //prev = temp;

        if (temp != NULL && temp->next == head)
        {
            head->next = NULL;
            free(temp);
            head = NULL;
            return head;
        }

        if (temp != NULL && temp->status == true)
        {
            //temp = prev;
            prev->next = temp->next;
            free(temp);
            temp = prev->next;

        }
        else if(temp != NULL)
            temp = temp->next;
        if (temp == NULL)
            return head;
    } while (temp != NULL && first != temp);
    head = temp;
    return head;
}

现在,将数据推入其中可以正常工作。如果只有一个节点,删除也可以正常工作。但是当要删除多个节点时,它会崩溃。

delete_nodes() 函数由线程调用,该线程处理数据(如果有)并调用 delete_nodes()

以下语句导致了问题

prev->next = temp->next; // what is prev here ?

应该是

if (temp != NULL && temp->next !=NULL && temp->status == true) {
        prev = temp;//current node which you want to delete 
        temp->next = prev->next;//this statement should be done before next statement..current node next should be prev node next
        prev->next = temp->next;//
        free(temp);
        temp = prev->next;
  }

这个代码块

    if (temp != NULL && temp->status == true)
    {
        //temp = prev;
        prev->next = temp->next;
        free(temp);
        temp = prev->next;

    }

第一次迭代肯定是错误的。

在第一次迭代时 prevtemp 都与 head 相同。所以 prev 指向与你 free-ing 相同的内存。

考虑放弃对 NULL 的所有检查,只检查开始,即

struct data* delete_nodes(struct data *head)
{
    if (head == NULL) return NULL;
    // Hereafter no further checks for NULL is needed

一个完整的函数可能如下所示:

struct data* delete_nodes(struct data *head)
{
    if (head == NULL) return NULL;

    struct data *prev = NULL;
    struct data *temp = head;
    struct data *first = head;

    do
    {
        struct data *next = temp->next;
        if (temp->status)
        {
            if (prev == NULL)
            {
                // Delete head element
                head = temp->next;
            }
            else
            {
                // Delete middle element
                prev->next = temp->next;
            }
            free(temp);
        } 
        else 
        {
            prev = temp;
        }
        temp = next;
    } while (temp != first);

    if (prev == NULL)
    {
         // List is empty
         return NULL;
    }
    return head;
}