-2

I tried to make a function that would add a node to the beginning of the list, and then change the variable "head" (holding the previous beginning of the list) to contain the new node.

void addToStart(node * n, node * first){
   printf("[Before adding] Node: %d, First: %d\n",&(*n),&(*first));
   n->next = first;
   first = n;
   printf("[After adding] Node: %d, First: %d\n",&(*n),&(*first));
}


int main(){
    node * head = createNode(0);
    printf("This is the location of head: %d\n",&(*head));
    node * fred = createNode(2);
    addToStart(fred,head);
    traverse(head); //Displays the list starting from the given node
    return 0;
}

This is the output:

This is the location of head: 10113040                                                                                                                                                   
[Before adding] Node: 10113072, First: 10113040                                                                                                                                          
[After adding] Node: 10113072, First: 10113072                                                                                                                                           
(0)[10113040]->NULL

The problem is that I expected the function to change what head was pointing at, but in reality nothing has changed.

  • `first = n` changes the function parameter `first` in `addToStart`, but not `head` from `main`. `first` is a copy of `head`, because C is pass-by-value, and only the copy is changed. – Tavian Barnes Aug 29 '16 at 14:58
  • This is the same reason that `void f(int n) { n = 0; }` cannot be used to set an integer to zero. As with all things in C, try to first understand the situation for `int`, and then generalize to other types. – Kerrek SB Aug 29 '16 at 15:01
  • You are right about the 'int' situation, but aren't pointers referring to a variable, rather than holding the variable itself? I assumed passing a pointer variable and changing the pointer would effectively change the original variable as well. – Adnan Zaman Sep 08 '16 at 00:51

1 Answers1

1

Because addToStart takes a copy of the head pointer as a node *. To change the head, you need to use

void addToStart(node * n, node ** first){
                           //   ^
   printf("[Before adding] Node: %d, First: %d\n",&(*n),&(**first));
   n->next = *first;
          // ^
   *first = n;
// ^
   printf("[After adding] Node: %d, First: %d\n",&(*n),&(**first));
}

Edit Every function in C gets its own copy of the parameters, so there's really no such thing as a reference like in C++ or other languages. Wherever you would use a reference, the quick-and-dirty option (which may not always work!) is to stick an extra * in front of each mention. Here, you wanted first to be a reference. first is a node pointer, so it's already a node *. To use it as a "reference" (as it were), it gets an extra *, hence node **. Similarly, wherever it is referred to, it gets an extra *: *first = ....

See a Java answer that's related for more about Java internals. Basically, the first * is implicit in Java instance variables. So Node n; in Java is (sort of) like Node *n; in C.

Hope that helps - definitely check out the linked duplicate question at the top of the page, and the answers there. If you run into another code problem, just ask another question!

Note to the C wizards: Yes, I know blindly adding * is a bad idea! It is useful sometimes, though. I'm trying to respond to the OP's comment in a way that will move the OP one step forward.

Community
  • 1
  • 1
cxw
  • 16,685
  • 2
  • 45
  • 81
  • Thank you I understand what you did..but I think this made me realize a misunderstanding I might have. I thought a pointer was analogous to a reference variable in Java; so when I passed the argument 'node * first' and 'node * n', wouldn't doing 'first = n' change the pointer? – Adnan Zaman Sep 08 '16 at 00:50
  • @AdnanZaman Edited :) – cxw Sep 08 '16 at 01:30
  • Now that is something I did not know! Wow that makes a lot of errors I've had in the past make so much more sense now. These errors don't seem so mystical anymore. I suppose this is what they mean by "pass-by-value". Thank you so much! – Adnan Zaman Oct 03 '16 at 20:57