0

I have written some code to create a singly linked list of integers and print out the items. After printing out all the items in the list, I printed out "head->item" and got the value of the integer in the first node.

I am quite puzzled as to why I can do that, because in the print() function, I wrote "head = head->next", so that means that head is changed right?

main()
    int n;
    int value;
    ListNode *head = NULL;
    ListNode *temp = NULL;
    printf("Enter a value: ");
    scanf("%d", &n);
    while (n != -1)
    {
        if (head == NULL)
        {
            head = malloc(sizeof(ListNode));//create the head first
            temp = head;//get temp to have the same value as head, so we do not accidently edit head
        }
        else
        {
            temp->next = malloc(sizeof(ListNode));//allocate space for the next node
            temp = temp->next;//let temp be the next node
        }
        temp->item = n;//allocate a value for the node
        temp->next = NULL;//specify a NULL value for the next node so as to be able to allocate space
        scanf("%d", &n);
    }
    print(head);
    printf("%d\n", head->item);//why can I still get the integer in the first node
    while (head != NULL)
    {
        temp = head;
        head = head->next;
        free(temp);
    }
    head = NULL;
    return 0;
}
void print(ListNode *head)
{
    if (head == NULL)
    {
        return;
    }
    while (head != NULL)
    {
        printf("%i\n", head->item);
        head = head->next;
    }
}
mib1413456
  • 337
  • 1
  • 3
  • 16

1 Answers1

4

head could be seen as a "reference" to a list, but it's actually a number (the address of the first node). So a call to a function with head as a parameter just copy this "number" (the address) to the stack, and creates a new variable (which is also named head) initiated with the same address. Since the head inside the function is a different variable, changing it doesn't change the original head.

Consider this situation:

void func(int x)
{
    x=1;
}
...
int x=0;
func(x);
printf("%d",x); //Prints '0'
...

Make sure you understand why in this simple example the value of x isn't changed. It's true that pointers seem to change the behavior of parameter passing, but it doesn't mean that suddenly everything is passed "by reference".

Remember this rule: in order to modify the value of a variable in a function, you need to send a pointer to the variable. So what happens when you want to change a pointer to a variable? Well, according to the rule, you'll have to pass a pointer to the pointer.

So if you'd like to modify head (which you probably don't), refactor it like this:

void print(ListNode **head)
{
    if (*head == NULL)
    {
        return;
    }
    while (*head != NULL)
    {
        printf("%i\n", *head->item);
        *head = *head->next;
    }
}

And the actual call is now print(&head).

Benesh
  • 3,398
  • 1
  • 18
  • 38