删除可被 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->link
是 NULL
) 因此你的段错误。
始终使用循环内的当前节点。您唯一必须使用 temporary->link
的时间是在循环结束时,以便切换到下一个节点(temporary = temporary->link
就像您所做的那样)。
我正在尝试创建一个函数来删除链表中的所有节点,这些节点的值可以被所选数字整除。
代码如下:
#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->link
是 NULL
) 因此你的段错误。
始终使用循环内的当前节点。您唯一必须使用 temporary->link
的时间是在循环结束时,以便切换到下一个节点(temporary = temporary->link
就像您所做的那样)。