Why I need to add '&' when calling the function - c

typedef struct sTree {
int key;
struct sTree* p;
struct sTree* left;
struct sTree* right;
} sTree;
typedef sTree* tree;
void treeInsert(tree* root);
int main(){
srand((unsigned)time(NULL));
tree *root = NULL;
treeInsert(&root);
return 0;
}
void treeInsert(tree* root){
......
}
I don't understand why I have to pass '&' when calling tree insert (&root instead of root).
I've created a struct representing a node of binary tree and I declared a pointer to the root of the tree as 'tree*'.
So 'root' is double pointer. The function 'treeInsert' expects a double pointer. If I pass simply 'root' it takes the value (NULL) else with the operator '&' it points correctly to the root. The problem is:
passing '&root' I'm not passing a triple pointer? Can someone explain why?

regarding:
treeInsert(&root);
the need for the & is because the function: treeInsert() will need to modify the contents of the pointer. Without the & any assignment to that passed parameter will only change the parameter on the call stack and not the the contents of the parameter in main()
regarding:
tree *root = NULL;
Since tree is already a pointer, this results in (effectively)
tree ** root = NULL;
which will not accomplish what is needed.
A prime example of why a pointer should NOT be hidden in a typedef statement
the following proposed code is clear about what is wanted:
struct sTree
{
int key;
struct sTree* p;
struct sTree* left;
struct sTree* right;
};
typedef struct sTree tree;
void treeInsert(tree** root);
int main( void )
{
srand((unsigned)time(NULL));
tree *root = NULL;
treeInsert(&root);
return 0;
}
void treeInsert(tree** root)
{
tree *localroot = *root; // now 'localroot' is a pointer to the variable `root` in function: `main()`
......
}

Related

Count occurrences in binary tree in C

struct tree{
struct node* root;
};
typedef struct tree* Tree;
struct node{
int key;
struct node* left;
    struct node* right;
};
typedef struct node* node;
My problem is that the function I need to implement requires as a parameter a Tree and not a Node.
int count_occurrences(Tree t, int k){}
I know how to implement this function if the first parameter was of type Node, but since it needs a type Tree I can't figure it out how to pass the type Tree parameter in the recursive calls.
EDIT: Also there is another problem. I can't access struct fields directly since they are declared in another file (school project). I have access to some functions like getting the root of a tree, left or right child of a node etc
Tree newtree();
int treeempty(Tree t);
Node root(Tree t);
int readInfo(Node v);
void setInfo(Node v, int x);
Node leftChild(Node v);
Node rightChild(Node v);
One straightforward way is to create a helper function:
int count_occurrences_helper(node d, int k) {
/* You already know how to implement this. */
}
int count_occurrences(Tree t, int k) {
return count_occurrences_helper(t->root, k);
}

malloc structure C

I can't understand why this litle code doesn't work ! i get it from C struct and malloc problem (C) (selected answer) and I wonder why it doesn't work for me.
any idea ?
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *leftChild;
struct node *rightChild;
} node;
typedef struct tree {
int numNodes;
struct node** nodes;
} tree;
tree *initTree() {
/* in C code (not C++), don't have to cast malloc's return pointer, it's implicitly converted from void* */
tree* atree = malloc(sizeof(tree)); /* different names for variables */
node* anode = malloc(sizeof(node));
atree->nodes[0] = anode; // <-------- SEG FAULT HERE !
return atree;
}
int main() {
tree* mytree = initTree();
return 0;
}
With a call to
tree* atree = malloc(sizeof(tree));
you have allocated a memory for tree object, so for a struct node** nodes pointer to (as it is a struct member), but it doesn't point to valid memory yet. You have to allocate also a memory for the nodes to which it is supposed to point to. For example:
atree->nodes = malloc( atree->numNodes*(sizeof (node*)));

Creating a binary tree but it doesn't work — tree is always null

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));
//...
}

Adding elements to linked list inside a linked list in C

I'm trying to create a small list for each element in a main list. I have the main list working fine but I don't know how to access and add elements to the small list.
struct smallList
{
char data;
struct smallList *next;
};
struct bigList
{
char data;
struct bigList *next;
struct smallList *head;
} *root;
When I add stuff to the main list, I declare for each new node:
newNode->head = NULL;
I use this function to get the current pointer to an element in main list:
struct bigList *pointer = getPointer(root, value);
Then, to add stuff to its smallList| using that pointer. I pass alongpointer->head` to this function. And its not working.
insert(pointer->head, value)
As WhozCraig suggests, you can resolve your problem using a pointer to a pointer. Something like this:
void insert(struct smallList **head, char value)
{
*head = newSmallList(value, *head);
}
newSmallList would be something like:
struct smallList *newSmallList(char value, struct smallList *rest)
{
struct smallList *result = malloc(sizeof(struct smallList));
result->next = rest;
result->data = value;
return result;
}
The problem with your current setup is that you are passing the value of the pointer->head field (which happens to be null) to the function, when what you want is to alter what is stored in the field. Here is a program using integers that illustrates a similar mistake:
void setFive(int i)
{
i = 5;
}
int main(void)
{
int myInt = 7;
setFive(myInt);
printf("%d\n", myInt); /* still 7! */
return 0;
}

changing struct/variable content in C

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;
}
}

Resources