-1

The struct that will represent the node of the linked list:

typedef struct node{
    int val;
    struct node *next;
} node_t;

and the head of our list:

node_t *head;

Now, I wanna build a function that creates the first element in the list, of course that will be pointed by *head. I am gonna start with the correct version, in my point of view, of the function, where I used a pointer who points to head, namely a double pointer:

void createFirstElement(node_t **head, int value){
    *head=NULL;
    *head=malloc(sizeof(node_t));
    (*head)->val=value;
    (*head)->next=NULL;
}

When I used that version of createFirstElement I got the value of the node printed. However I have a question for my first version of createFirstElement which didn't worked:

void createFirstElement(node_t *head, int value){
        head=NULL;
        head=malloc(sizeof(node_t));
        head->val=value;
        head->next=NULL;
 }

How is this version different from the one with double pointers? I am still getting the head pointer in parameter (instead of a pointer that points to head) and make all the changes inside.

Thanks everyone in advance!

Mr T
  • 506
  • 2
  • 9
  • 26
  • 1
    You'll figure it out if you always ask *"What does it point to?"*. In the first working code sample, `head` point to the variable you initialize. Hence you see the value updated. In the second case, `head` merely points to an address you allocated. The address is the *value* you want to initialize the variable *outside* the function with. – StoryTeller - Unslander Monica Feb 11 '16 at 11:53
  • Just an unrelated query, why do you initialize the `*head` pointer to `NULL` when you reassigning it the very next line? The assignment from the result of `malloc` makes the first assignment to `NULL` pointless. – Some programmer dude Feb 11 '16 at 11:56
  • Yeah maybe its a stupid decision, I read something yesterday about valid and invalid pointer, how dangerous they can be and stuff. Even I don't know why I did that. – Mr T Feb 11 '16 at 12:06
  • I do - cargo-cult 'You must initialize all variables upon declaration'. I'm guessing that many compilers will just remove the init. if the next line loads the var, (?). – Martin James Feb 11 '16 at 12:49

1 Answers1

3

C uses "call by value", so in the second version you are working with a copy of node_t *head. When the function returns, the head which was passed to the function remains unchanged.

alain
  • 11,939
  • 2
  • 31
  • 51
  • Sorry but I think I am loosing something here. The node_t *head; is initialized globally and when I am gonna use the wrong version of the createFirstElement() I am gonna pass as argument the globally declared pointer. So all the changes inside the function shouldn't be as well to the *head? I know you are right but I don't know why! :) – Mr T Feb 11 '16 at 12:02
  • 1
    All the arguments are copied before the function is called. If you change the copy, the original remains the same. With the first version, you don't change a copy, but you change the variable the double pointer points to. – alain Feb 11 '16 at 12:13
  • Jesus thank you so much. I had done some Java in the past so I took that for granted! – Mr T Feb 11 '16 at 12:18
  • Can I ask one last thing out of curiosity? C++ also uses "call by value"? – Mr T Feb 11 '16 at 12:21
  • 2
    Yes, C++ is also call by value. ([Java is call by value too](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value), btw, but it's confusing because all class variables are references in Java). – alain Feb 11 '16 at 12:41
  • 1
    @Skemelio Assigning to a parameter has the same effect in Java as in C, and in C++, and in JavaScript, and in Lisp, and in Pascal, and in C#, and in Go, and.... – molbdnilo Feb 11 '16 at 12:56