0
$\begingroup$

The following code is from GeeksForGeeks

void deleteN(Node** head, int position)
{
    Node* temp;
    Node* prev;
    temp = *head;
    prev = *head;
    for (int i = 0; i < position; i++) {
        if (i == 0 && position == 1) {
            *head = (*head)->next;
            free(temp);
        }
        else {
            if (i == position - 1 && temp) {
                prev->next = temp->next;
                free(temp);
            }
            else {
                prev = temp;

                // Position was greater than
                // number of nodes in the list
                if (prev == NULL)
                    break;
                temp = temp->next;
            }
        }
    }
}

void printList(Node* head)
{
    while (head) {
        printf("[%i] [%p]->%p\n", head->number, head,
            head->next);
        head = head->next;
    }
    printf("\n\n");
}
  1. Why are we calling a pointer to the head pointer that already represents the entire linked list in the delete function? Why are we not doing the same in the display function?
  2. What is the difference between traversing via *head=(*head)->next and ``` head=head->next ``` methods?
$\endgroup$

2 Answers 2

0
$\begingroup$

That's poorly written, confusing code, and it would be better not to study it too closely. That said, there is a good reason it takes a Node**. The pointer to the first node may change when deleting a node, if the deleted node is the first one, so deleteN has to communicate the new value to the caller. It could have done that by returning it, in which case calls to deleteN would have to look like

head = deleteN(head, position);

But if you did it that way, accidentally ignoring the return value would silently produce buggy code (and the worst kind of buggy code—undefined behavior—because head would be left pointing to a freed heap object). So it's probably better to do what they did, and make the caller pass head by reference so that it can't fail to be updated.

*head = (*head)->next is not traversing the list. It's updating the caller's pointer, and it happens at most once per call of deleteN.

$\endgroup$
0
$\begingroup$

In deleteN, head needs to be a pointer to pointer, because its value might be modified in the function (due to that miserable lack of by-reference argument passing). In printList, it is a plain pointer.

Note that calling both arguments the same way is poor practice (ppHead and pHead could have been better; this emphasizes than in all accesses ppHead requires one more indirection than pHead).

ppHead= ppHead->next would just not work, as ppHead is a pointer to a pointer, and does not have a next field (it has no field at all).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.