1

I'm writing a function to insert into a tree and the data can be seen (printed) after insertion within the function but when trying to see it in main nothing happens.

node *tree = NULL;
insert(tree, 4321);
printf("outer: %d\n", tree->data);

void insert(node* tree, int data) {
  if (tree == NULL) {
    tree = new_node(data);
    printf("inner: %d\n", tree->data);
  }
}

This gives:

inner: 4321

It should be:

inner: 4321
outer: 4321
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Fraser Langton
  • 471
  • 3
  • 12
  • 2
    Classic problem of [pass by value vs pass by reference](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) – Pratik Sampat May 29 '19 at 06:40
  • I your code tree is a pointer to a variable. When you call tree = xxx you set the pointer to a new memory location and the original tree pointer is unaltered, pointing to the old empty tree – Aram Becker May 29 '19 at 06:40

2 Answers2

8

The problem is, tree is passed as an argument to the function, and by-status which is a pass-by-value in C. Any change made to tree itself inside the function will not be reflected back to the caller.

You need to pass a pointer to tree, if you want to modify tree from the called function.

Something like

void insert(node** tree, int data) {
  if (*tree == NULL) {
    *tree = new_node(data);
    printf("inner: %d\n", (*tree)->data);
  }
}

and call it like

insert(&tree, 4321);
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • ```node *tree = NULL;``` means it's a pointer does it not? – Fraser Langton May 29 '19 at 06:50
  • @FraserLangton Yes, but check carefully, what are you trying to change from the called function, the content of the memory pointed to by the pointer, or the pointer itself? Pointer or not, all function arguments are passed by value in C. – Sourav Ghosh May 29 '19 at 06:52
  • @Fraser Langton, Re "*`node *tree = NULL;` means it's a pointer does it not?*", Yes, but it's not a pointer to that which you want to modify. You want to modify the caller's `tree`, so you need to pass a pointer to the caller's `tree`. – ikegami May 29 '19 at 07:02
  • Got it! Thanks for the help. – Fraser Langton May 29 '19 at 07:20
1

You initialize tree as a pointer

node *tree = NULL;

This means, that the content of the variable is a memory location where your tree is stored.

When you pass that memory location to a function, it's value gets copied to the local variable inside the function.

When you call

tree = new_node(data);

what you're doing is assigning a new memory location to the local variable of the tree pointer inside your function. The pointer outside your function still has the same value and points to a memory location with no nodes.

What you'll need to do in order to edit the node inside your function is either define some kind of setter for your node, or set the data property explicitly with tree->data = xxx. This will alter the content of the memory tree is pointing to rather than altering its memory location.

Aram Becker
  • 2,026
  • 1
  • 20
  • 32