无法使用c

时间:2018-01-27 15:23:47

标签: c circular-list

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

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()

2 个答案:

答案 0 :(得分:0)

以下声明导致问题

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

答案 1 :(得分:0)

此代码块

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