我在C编程的双向链接列表中有问题下一个指针的错误

问题描述

struct someEvent
{
    int id;
    int shouldRemove;
    struct someEvent *prev;
    struct someEvent *next;
} * someEvent;


struct someEvent *someEventQueue = NULL;


int main(){

struct someEvent **curr5 = &someEventQueue;
                while ((*curr5) != NULL)
                {
                    if ((*curr5)->shouldRemove == 1)
                    {
                        tmpflag = 1;
                        if ((*curr5)->prev == NULL && (*curr5)->next == NULL)
                        {
                            (*curr5) = NULL;
                        }
                        else if ((*curr5)->prev == NULL)
                        {
                            (*curr5) = (*curr5)->next;
                            (*curr5)->prev = NULL;
                            //(*curr5)->prev->next = (*curr5)->next;
                        }
                        else if ((*curr5)->next == NULL)
                        {
                            (*curr5)->prev->next = NULL;
                        }
                        else
                        {
                            (*curr5)->prev->next = (*curr5)->next;
                            (*curr5)->next->prev = (*curr5)->prev;
                        }
                    }
                    if (tmpflag == 1)
                    {

                        break;
                    }

                    curr5 = &(*curr5)->next;
                }



  }

我这样编写代码。我想删除删除为1的节点。

enter image description here

图片是someEventQueue。我要删除ID为2的节点。

enter image description here

我想要这个结果。但是,我的结果有误...

enter image description here

图片是我的代码的结果。调试后,我发现为什么它有错误(*curr5)->prev->next = (*curr5)->next;这部分效果很好。但是,在这部分(*curr5)更改为(*curr5)->next (*curr5)->next->prev = (*curr5)->prev;之后,此代码返回分段错误。我不知道为什么会发生这种变化。为了解决此问题,我在(*curr5)=(*curr5)->prev;(*curr5)->prev->next = (*curr5)->next;之间添加(*curr5)->next->prev = (*curr5)->prev;。然后,这陷入无限循环...我认为我的代码没有错误,但是我不知道为什么 (*curr5)->prev->next = (*curr5)->next;之后更改(* curr5)。我需要一些建议。

解决方法

您正在使它变得比所需的复杂。出现代码 想要删除列表中设置了shouldRemove标志的第一个节点,然后停止。二重链接列表中的节点管理涉及两件事:

  • 将您带到那里的指针。
  • 保存该指针的节点(如果有)。

int main()
{
    struct someEvent **curr = &someEventQueue;
    struct someEvent *prev = NULL;

    while (*curr)
    {
        if ((*curr)->shouldRemove)
        {
            struct someEvent *tmp = *curr;
            *curr = tmp->next;
            if (tmp->next)
                tmp->next->prev = prev;

            // added to prevent memory leak. remove if these are
            //  maintained somewhere else.
            free(tmp);

            break;
        }
        else
        {
            prev = *curr;
            curr = &(*curr)->next;
        }
    }
}

值得注意的是,您可以通过删除上述循环中的shouldRemove来删除设置了break;标志的 all 个节点。