For your purpose here, changing the value of the struct member, you don't need to make the function accept a pointer to a pointer to struct node. A single pointer to type struct node would suffice. This would eliminate the need for passing the address of root to the foo function and the extra dereferencing and use of parenthesis steps within the foo function. You could have simply done this and achieved the same effect:
Code:
struct node
{
int data;
struct node* next;
};
void foo(struct node* n ) // Single pointer
{
n->data = 5; // No extra parenthesis and dereferencing needed here
}
int main( void )
{
struct node* root = NULL;
root = malloc(sizeof(struct node));
root->data=3;
printf("root->data = %d", root->data);
foo( root ); // No address of operator (&) needed
printf("root->data = %d", root->data);
return 0;
}
Now, if on the other hand you wished to change what root pointed to by passing it in as a parameter, then you would need to use a pointer to a pointer to struct node, i.e.:
Code:
struct node
{
int data;
struct node* next;
};
void foo1(struct node* n )
{
n = (node*) malloc(sizeof(struct node));
n->data = 3;
}
void foo2(struct node** n )
{
*n = (node*) malloc(sizeof(struct node));
(*n)->data = 10;
}
int main( void )
{
struct node* root = NULL;
foo1( root);
if( root != NULL )
printf("root->data = %d after foo1\n", root->data);
else
printf("root is still NULL after foo1\n");
foo2( &root );
if( root != NULL )
printf("root->data = %d after foo2\n", root->data);
else
printf("root is still NULL after foo2\n");
return 0;
}
Which outputs:
Code:
root is still NULL after foo1
root->data = 10 after foo2
Or, foo2 could have been done as a void function returning a pointer to struct node and having the same effect:
Code:
struct node* foo2()
{
struct node *n = malloc(sizeof(struct node));
n->data = 10;
return n;
}
Which would be called like so:
Code:
struct node *root = NULL;
...
root = foo2();
if( root != NULL )
printf("root->data = %d after foo2\n", root->data);
else
printf("root is still NULL after foo2\n");