I have been reading something related to C language's double pointers, and I have some doubts about the following piece of code. The following piece of code is about the operation of deleting a node of single linked list using double pointers in C language.
#include<stdio.h>
#include<stdlib.h>
struct ListNode
{
int val;
unsigned should_remove:1;
struct ListNode* next;
};
struct ListNode* CreateList(int n)
{
struct ListNode* node;
struct ListNode* next_node = NULL;
int i;
for (i = n-1; i >= 0; --i) {
node = (struct ListNode*)malloc(sizeof(struct ListNode));
node->val = i;
node->next = next_node;
node->should_remove = i % 2;
next_node = node;
}
return node;
}
void RemoveList(struct ListNode* head){
struct ListNode* next;
while(head) {
next = head->next;
free(head);
head = next;
}
}
int IsRemove(struct ListNode* node)
{
return node->val == 4;
}
typedef int RemoveFn(struct ListNode*);
void PrintList(struct ListNode* head)
{
while(head->next) {
printf("%d, ", head->val);
head = head->next;
}
if(head) printf("%d\n", head->val);
}
void RemoveIf3(struct ListNode** head, RemoveFn * Remove)
{
struct ListNode** ptr_current_node = head;
struct ListNode* entry;
while(*ptr_current_node) {
entry = *ptr_current_node;
if (Remove(entry)) {
*ptr_current_node = entry->next;
free(entry);
} else {
ptr_current_node = &entry->next;
}
}
}
int main()
{
printf("test 3: ");
struct ListNode* head3 = CreateList(10);
struct ListNode** p = &head3;
RemoveIf3(p, IsRemove);
PrintList(*p);
return 0;
}
And it can used gcc compile and run OK.
gcc test.c -o test
./test
However I change the func RemoveIf3 one line of code:
ptr_current_node = &entry->next;
to:
*ptr_current_node = entry->next;
and the function code will change like this:
void RemoveIf3(struct ListNode** head, RemoveFn * Remove)
{
struct ListNode** ptr_current_node = head;
struct ListNode* entry;
while(*ptr_current_node) {
entry = *ptr_current_node;
if (Remove(entry)) {
*ptr_current_node = entry->next;
free(entry);
} else {
*ptr_current_node = entry->next;
}
}
}
And it can be compile,but when we run it and will have a error:
Segmentation fault (core dumped)
the first if remove branch can use pointer like this: *ptr_current_node = entry->next;, why the other branch can not use double pointer such as this, what wrong with it?

struct ListNode** p = &head3; RemoveIf3(p, IsRemove);is a complicated and confusing way of writingRemoveIf3(&head3, IsRemove);