删除可被 2 整除的节点会产生 SIGSEGV 错误

Removing nodes divisible by 2 gives a SIGSEGV error

我正在尝试创建一个函数来删除链表中的所有节点,这些节点的值可以被所选数字整除。

代码如下:

#include <stdio.h>
#include <stdlib.h>

//add_beg - adds node at beginning
//add_end - adds node at the end
//add_at - adds node at the specified index
//remove_divisible_by - removes node if divisible by num (SIGSEGV)
//print_nodes - prints nodes


struct node
{
    int value;
    struct node *link;
};
typedef struct node node_t;

node_t *head = NULL;

void remove_divisible_by(int num)
{
    node_t *temporary = head;

    while(temporary != NULL) //ERROR IS PROBABLY HERE
    {
        if(temporary->link->value % num == 0) 
        {
            temporary->link = temporary->link->link;
        }

        temporary = temporary->link;

    }
}

void add_at(int index, int value)
{
    node_t *new_node_ptr = calloc(sizeof(node_t),1);

    new_node_ptr->value = value;

    node_t *temporary = head;

    while(index>1)
    {
        temporary = temporary->link;
        index--;
    }

    new_node_ptr->link = temporary->link;
    temporary->link = new_node_ptr;

}

void add_beg(int value)
{
    node_t *new_node_ptr = malloc(sizeof(node_t));

    new_node_ptr->value = value;
    new_node_ptr->link = head;

    head = new_node_ptr;
}

void add_end(int value)
{

    node_t *new_node_ptr;

    new_node_ptr = malloc(sizeof(node_t));

    new_node_ptr->value = value;
    new_node_ptr->link = NULL;

    if(head == NULL)
    {
        head = new_node_ptr;
        return;
    }

    node_t *temporary;
    temporary = head;

    while(temporary->link != NULL) temporary = temporary->link;

    temporary->link = new_node_ptr;


}

void print_nodes(node_t *head)
{
    node_t *temporary;
    temporary = head;
    while(temporary != NULL)
    {
        printf("%d ",temporary->value);
        temporary = temporary->link;
    }
}

int main()
{
    add_end(2);
    add_end(3);
    add_end(5);

    add_beg(1);

    add_at(3,4);

    remove_divisible_by(2);

    print_nodes(head);

    return 0;
}

错误似乎在函数中 remove_divisible_by

发生了什么: 如果我想删除可被 2 整除的节点,我会收到 SIGSEGV 错误。 如果我想删除列表中的最后一个节点(在本例中为可被 5 整除的数字),它会起作用。

另一方面,如果我在 remove_divisible_by 函数中写入 while(temporary->link != NULL),删除可被数字 2 整除的节点实际上是有效的,但是如果我想删除,我会收到 SIGSEGV 错误最后一个节点(可被 5 整除的节点)

我的问题是,为什么会发生这种情况,我该如何解决?

        if (temporary->link->value % num == 0)
        {
            temporary->link = temporary->link->link;
        }

...您不是在检查当前节点 (temporary),而是检查下一个节点 (temporary->link),它可能不存在(即 temporary->linkNULL) 因此你的段错误。

始终使用循环内的当前节点。您唯一必须使用 temporary->link 的时间是在循环结束时,以便切换到下一个节点(temporary = temporary->link 就像您所做的那样)。