This question already has answers here:
Changing address contained by pointer using function
(5 answers)
Closed 1 year ago.
I am trying to add a node to a binary search tree (BST). My adding method code is as follows:
int add(node_t* n, node_t* tn){
if(tn == NULL){tn = n;}
if(n->value < tn->value){add(n, tn->leftNode);}
else if (n->value > tn->value){add(n, tn->rightNode);}
else{return 0;}
return 1;
}
The method is called in main for BST t1 and node n1: add(n1, t1->root). The return value of the function is a 0 or 1, 0 if another node of the same value exists in the tree- in which case the new node is not added- and 1 if the node is successfully added. Struct tree_t's count variable is updated in the main function as follows: t1->count += add(n1, t1->root).
However, after I call the add function, the tree t1 still seems to be empty. My only guess is that add is adding a node to a copy of t1 which is being destroyed after the function call, but I don't understand why this is the case as it is passed in as a pointer.
The structs tree_t and node_t are attached below:
typedef struct node{
int value;
struct node* leftNode;
struct node* rightNode;
} node_t;
typedef struct tree{
struct node* root;
int count;
} tree_t;
And here is my main method:
int main(){
tree_t t1;
tree_init(&t1);
node_t n1;
node_init(&n1, 5);
node_t n2;
node_init(&n2, 7);
t1.count += add(&n1, t1.root);
t1.count += add(&n2, t1.root);
print_tree(t1.root); //this prints nothing, and I'm confident that print_tree works
}
Any help is greatly appreciated!
If you pass to function pointer to type, you can change the variable that pointer points to. But you can't change the address, that this pointer points to (can't change pointer itself).
If you want to change pointer itself (address that he points to), you need to pass in your function pointer to pointer:
int add(node_t *n, node_t **tn){
if(*tn == NULL){*tn = n;}
if(n->value < *tn->value){add(n, *tn->leftNode);}
else if (n->value > *tn->value){add(n, *tn->rightNode);}
else{return 0;}
return 1;
}
Related
This question already has answers here:
What is self-referencing structure in C?
(3 answers)
Closed 3 years ago.
Can someone explain what we mean when we do, like what does struct Node* next do. does it create a pointer of type struct? any help and resources about structures in c would be helpful
struct Node {
int dest;
struct Node* next;
};
"struct" itself is not a type. "struct [tag]" is a type, for example "struct Node" in your code.
In your case you define a structure type. Every structure of that type will contain a pointer to another structure of that type as a member called "next".
This allows you to chain the structures together in a so called linked list. You store a pointer to the first structure in a variable, then you can follow the chain of links down to the structure you need.
For example, you can do
struct Node *start;
start = malloc(sizeof struct Node);
start->dest = 7;
start->next = malloc(sizeof struct Node);
start->next->dest = 13;
start->next->next = malloc(sizeof struct Node);
start->next->next->dest = 19;
printf("%d %d %d\n", start->dest, start->next->dest, start->next->next->dest);
free(start->next->next);
free(start->next);
free(start);
Please note that this code omits all error handling, in real code you have to handle the case when malloc returns NULL.
Also, in real code you would use such a structure in loops that traverse the chain, not directly as above.
As #Serge is pointing out in comments, is not a struct within a struct, is a reference (a pointer) to an object of the same type, an example:
#include <stdio.h>
struct Node {
int dest;
struct Node* next;
};
int main(void)
{
/* An array of nodes */
struct Node nodes[] = {
{1, &nodes[1]}, // next points to the next element
{2, &nodes[2]}, // next points to the next element
{3, NULL} // next points to null
};
/* A pointer to the first element of the array */
struct Node *node = nodes;
while (node) {
printf("%d\n", node->dest);
node = node->next; // node moves to the next element
}
return 0;
}
Output:
1
2
3
Of course, in my example there is no benefit in using a linked list, linked lists are useful when we don't know the number of elements before-hand.
Another example using dynamic memory:
struct Node *head, *node;
node = head = calloc(1, sizeof *node);
node->dest = 1;
while (more_elements_needed) {
node->next = calloc(1, sizeof *node);
node->next->dest = node->dest + 1;
node = node->next;
}
for (node = head; node != NULL; node = node->next) {
printf("%d\n", node->dest);
}
I read those about tree in c:
struct node
{
int key_value;
struct node *left;
struct node *right;
};
/* insert a value to tree */
insert(int key, struct node **leaf)
{
if( *leaf == 0 )
{
*leaf = (struct node*) malloc( sizeof( struct node ) );
(*leaf)->key_value = key;
/* initialize the children to null */
(*leaf)->left = 0;
(*leaf)->right = 0;
}
else if(key < (*leaf)->key_value)
{
insert( key, &(*leaf)->left );
}
else if(key > (*leaf)->key_value)
{
insert( key, &(*leaf)->right );
}
}
I can't understand here: insert(int key, struct node **leaf) why two pointers **leaf, does *leaf ok? I am confused when to use two pointers.pls help, thank you very much!
In insert(int key, struct node **leaf) you are Passing the Address pointed by *leaf by C version of "Pass By Reference". And in insert(int key, struct node *leaf) you are passing the Address pointed by *leaf by Pass By Value method.Note C Parameter are always Passed by Value.
So, In This particular Case it doesn't matter if you use insert(int key, struct node **leaf) or insert(int key, struct node *leaf) both will achieve the same outputs.The only difference in this case is that in insert(int key, struct node **leaf) your passing the address by C version of Pass by Reference and in insert(int key, struct node *leaf) your passing the address by Pass By Value method.
Example Code A,
#include<stdio.h>
struct node
{
int data;
};
void AddFive(struct node **t);
int main()
{
struct node *n = NULL;
n = new node;
n->data = 5;
printf("%d\n", n->data);
AddFive(&n);
printf("%d\n", n->data);
return 0;
}
void AddFive(struct node **t)
{
(*t)->data = (*t)->data+5;
}
Example Code B,
#include<stdio.h>
struct node
{
int data;
};
void AddFive(struct node *t);
int main()
{
struct node *n = NULL;
n = new node;
n->data = 5;
printf("%d\n", n->data);
AddFive(n);
printf("%d\n", n->data);
return 0;
}
void AddFive(struct node *t)
{
t->data = t->data+5;
}
If you notice both Code A and Code B achieve the same output.
It is call by reference . if we have to change the value of *leaf then we should have its address thats why we used two *'s when is for pointer of leaf and other to get address of *leaf.
When you want to change the value of a variable defined in main() through some function. Think what do you do. You send the address of that variable and then using that address, change the content of that variable.
Now, in an example cases, the variable is of int type, so sending the address of that variable would mean in the function, you have to receive it in a variable of type int *
void test(int* var) {
*var++;
}
int main() {
int integer = 1;
test(&integer);
printf("%d", integer);
return 0;
}
To change the value of the variable integer you send the address of that to the function test().
Now take this same situation, and think if you need to change the content of a variable which is itself a struct node *. Then you send the address of that variable, and receive it with a (struct node *)*. Thats what is happening in the example you posted.
You want the changes that is to be made to the leaf variable in the insert() fucntion to reflect in the calling function. For this to take place you send the address and change the content accordingly.
C has only pass by value. If pointer to node struct is used as parameter then any modification to passed pointer will not be seen in the caller function. In that case you have to return a pointer from the function insert. Pointer to pointer is used here to update the pointer passed to function insert.
Case 1:
When you are passing a address of a variable then a single pointer is enough to access the variable
Example:
struct node a;
func(&a); // calling
In the func() definition:
func(struct node *a);
Here a points to the address of node. And we can access a using its address directly.
Case 2:
When you are sending the address of pointer variable:
struct node *a;
func(&a); // calling
Then in the function definition it should use a double pointer:
func(struct node **a);
This question already has answers here:
How can I allocate memory and return it (via a pointer-parameter) to the calling function?
(11 answers)
Closed 7 years ago.
I am having problem while initializing the node value to passed pointer in C language,
I have written something like follow,
#include<stdio.h>
#include<stdlib.h>
struct node{
int data;
struct node *next;
};
void add(struct node *head, int val){
struct node *n1 = NULL;
n1 = (struct node *)malloc(sizeof(struct node ));
n1 -> data = val;
n1 -> next = NULL;
if(head == NULL){
head = n1;
printf("Head2 is initialized");
return;
}
}
int main(){
struct node *ptr = NULL;
struct node *temp;
add(ptr, 11);
printf("\nData = %d", ptr->data);
return 0;
}
Could you please tell me what is the issue in this code,
When i execute
printf("\nData = %d", ptr->data);
System shows Windows has stopped working
Thanks
short answer: if you want to change the value the pointer points to, you have to pass the pointer to the pointer:
void add(struct node **head, int val) {
...
if(*head == NULL){
*head = n1
}
int main(){
...
add(&ptr, 11)
...
}
long answer: when you call add(ptr, 11) in main you pass a memory address and a number. both memory address and a number are passed by value. as the result the changes to these variables are both local
in your add method - when you assign a value to head in head = n1 you change the value of your local variable to point to a new memory address. when your function returns the changes are gone, so main never sees the assignment and ptr remains NULL.
if you pass a pointer to ptr - &ptr, you will pass a location in memory where the value of ptr (which is memory address) resides in main, so when you call *head = n1* you write the address ofn1` the value in this location will change, and main will see it.
see also this question
I am creating a code to insert the elements in tree, but tinsert function does not insert; what is wrong with my code? I have checked many times but tree is always NULL.
The code has only 2 functions: one to insert, and second to show it in preorder.
#include<stdio.h>
#include<stdlib.h>
struct btree {
int val;
struct btree *left;
struct btree *right;
};
static int c=0;
typedef struct btree node;
void tinsert( node *n,int a)
{
c++;
printf("%d\n",c);
if(n==NULL)
{
n=(node *)malloc(sizeof(node));
n->left=NULL;
n->right=NULL;
n->val=a;
//printf("adding root %d\n",n->val);
//n=temp;
}
else if(a>=(n->val))
tinsert(n->right,a);
else
tinsert(n->left,a);
return ;
}
void preorder_display(node *n)
{
if(n!=NULL)
{
printf("%d\n",n->val);
preorder_display(n->left);
preorder_display(n->right);
}
else
printf("tree is null\n");
}
int main()
{
//int N;
//int num[100];
//int i;
node *ntree=NULL;
tinsert(ntree,4);
tinsert(ntree,6);
tinsert(ntree,8);
tinsert(ntree,1);
printf("tree is \n");
preorder_display(ntree);
return 0;
}
tinsert works on a local copy of your ntree, it doesn't change the one in your main. You can fix it by passing a pointer to it (i.e.: double pointer, pointer to a pointer).
So your tinsert will look like this:
void tinsert( node **n,int a)
And in your main you'll call it like this:
tinsert(&ntree,4);
Of course, you'll need to adjust the code in tinsert to de-reference the pointer and access it correctly.
Or allocate the root node in your main.
you pass your root node ntree to tinsert function by value, so when when the function is done you will stay with original value of ntree which is NULL.
You better rewrite your function, so you will pass pointer to pointer
void tinsert( node **n,int a)
//and invocation is like that :
tinsert(&ntree,4);
when you pass ntree from main to tinsert function,
new copy is created to your node*n;
One way is to make use of pointer to pointer
Or second solution is here:
Here is a solution:
#include<stdio.h>
#include<stdlib.h>
struct btree{
int val;
struct btree *left;
struct btree *right;
};
static int c=0;
typedef struct btree node;
node* tinsert( node *n,int a)
{
c++;
printf("%d\n",c);
if(n==NULL)
{
n=(node *)malloc(sizeof(node));
n->left=NULL;
n->right=NULL;
n->val=a;
//printf("adding root %d\n",n->val);
//n=temp;
}
else if(a>=(n->val))
tinsert(n->right,a);
else
tinsert(n->left,a);
return n;
}
void preorder_display(node *n)
{
if(n!=NULL)
{
printf("%d\n",n->val);
preorder_display(n->left);
preorder_display(n->right);
}
else
printf("tree is null\n");
}
int main()
{
//int N;
//int num[100];
//int i;
node *ntree=NULL;
ntree=tinsert(ntree,4);
ntree=tinsert(ntree,6);
ntree=tinsert(ntree,8);
ntree=tinsert(ntree,1);
printf("tree is \n");
preorder_display(ntree);
return 0;
}
C supports the pass by value only. However, this does not prevent you from modifying the value of a variable from another function, because you can always refer to a variable using it's memory; and in C it's done through pointers, an abstraction representing a memory location.
When you pass a value to the function, the value of the actual parameter is copied to the value of formal parameter. Note that a pointer's value is the address it points to. So, this value is copied into the formal parameter. So the new pointer inside the function points to the exact same location your original variable. You can deference the pointer anytime to manipulate it's value.
Here, you are required to manipulate a pointer. So you pass a pointer-to-pointer to the function:
tinsert(&ntree,4);
In your function, you deference it to get your original pointer; like the following:
void tinsert(node **n, int a)
{
//...
*n = malloc(sizeof(node));
//...
}
I would like to get some help with the following question.
I have a struct Node and I want to change it's insides using some method.
and I want to print the content of the changed struct inside my main method.
how do I get the struct changed and see the changed value in my main without returning the node as a return value.
I guess it might be solved with passing the struct Node as a pointer and then editing it.
what is the right way to do so?
for example:
typedef struct Node{
struct Node * right;
struct Node * left;
void * data;
}Node;
void insert(void * element, Node* root){
if(root==NULL){
root=(Node*)malloc(sizeof(Node));
root->data=element;
}
}
int main(){
Node a;
int b=8;
insert(&b,&a);
printf("%d",*(int*)a.data);
return 0;
}
printf doesn't print 8 it prints 1 (i guess some garbage)
It sounds like you are trying to do the following
Create a struct in one method, say main
Pass it to a second method, say example
Have example modify the struct and have the results visible in main
If so then the way to do this in C is by passing the struct as a pointer to example.
struct Node {
int data;
struct Node* pNext;
};
void example(struct Node* pNode) {
pNode->data = 42;
pNode->pNext = NULL;
}
int main() {
struct Node n;
example(&n);
printf("%d\n", n.data);
}
EDIT
Responding to the updated question.
To see the result of a modification of a Node you must pass a Node*. And accordingly to see the result of a Node* modification you need to pass a Node**. Essentially you need to pass one more level of indirection than the value you want to mutate / return.
void insert(void* element, Node** ppRoot){
if (NULL == *ppRoot) {
Node* pTemp = malloc(sizeof(Node));
pTemp->data = element;
*ppRoot = pTemp;
}
}