I am creating a program in which you can and delete a node at any time. However, when I try to delete the last node in the list, the program crashes. Can somebody tell me what I am doing wrong?
void delete_node(Node **head_ref) {
int position, counter = 0;
Node *curr_node = *head_ref;
if(*head_ref == NULL) {
printf("No nodes to delete!");
return;
}
printf("Enter position between 1 and %d: ", node_number);
scanf("%d", &position);
if(position == 1) {
*head_ref = (*head_ref)->next;
free(curr_node);
} else if(position == node_number) {
while(counter != position) {
counter++;
if(counter == position - 1)
curr_node->next = NULL;
curr_node = curr_node->next;
}
}
printf("\nNode deleted successfully!\n");
if( *head_ref == NULL )
printf("\nLast node deleted!\n");
}
I am calling the function in main
:
int main() {
//... other part of the program
delete_node(&head);
}
In the while loop, you do
while(counter != position) {
counter++;
if(counter == position - 1)
curr_node->next = NULL;
curr_node = curr_node->next;
}
Let's take the example of a list with 3 nodes:
I'll use (°) to identify the Node pointed by curr_node.
you only change variables.
counter
. Then counter' value is now 2.curr_node = curr_node->next;
that results in cur_node = NULL
. Finally, you end the second iteration with the following status:cur_node = NULL
counter = 2
counter != position
, that is still true. So you have a third iteration:curr_node = curr_node->next;
, that causes the crash because curr_node is actually NULL. while (counter != position -1)
When counter == position - 1
you set current->next
to NULL
, but there will be one more iteration of the loop, and in that iteration current
will be NULL
and so you will run into an exception when you access current->next
in that final iteration.
Some things you can do:
prev_node
reference, that follows curr_node
one step behind.counter
as you can decrease the value of position
instead.else
case as currently you only do that when deleting the head node.node_number
when the deletion is successful.Here is some updated code:
void delete_node(Node **head_ref) {
int position;
Node *curr_node = *head_ref;
if(*head_ref == NULL) {
printf("No nodes to delete!");
return;
}
printf("Enter position between 1 and %d: ", node_number);
scanf("%d", &position);
if (position == 1) {
*head_ref = (*head_ref)->next;
} else { // All other positions can be treated in the same way
Node *prev_node = curr_node; // Maintain a separate reference for previous node
curr_node = curr_node->next;
while (curr_node != NULL && position > 2) { // Can use position without counter
prev_node = curr_node;
curr_node = curr_node->next;
position--;
}
if (curr_node == NULL) { // The input position was too great
printf("\nThere is no node at that position!\n");
return;
}
prev_node->next = curr_node->next;
}
free(curr_node);
node_number--; // Don't forget to keep this updated
printf("\nNode deleted successfully!\n");
if (*head_ref == NULL)
printf("\nLast node deleted!\n");
}
NB: It would be better if you would not deal with I/O inside this function, and instead pass the position as a separate argument. Deal with I/O only in the main program code. The function could return a boolean or int indicating whether the node was found and deleted or not. The caller should deal with printing messages.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.