I was writing a program to implement BST and I declareed two structures for that.
struct node
{
int data;
struct node *link[2];
};
struct tree
{
struct node *root;
};
typedef struct node node;
typedef struct tree tree;
And then i wrote a function to insert the elements in it.
void insert_iter(tree *tree, int data);
But in my main() function, I got confused that what thing shoud I initialise as NULL. So, I did this in my main() function.
tree *tree=NULL;
And it gave an error of segmentation fault.
But then I realised that the first condition in my insert_iter() function calls for tree->root, so this error was bound to happen.
But then I am confused about how to initialize this. How to go on for this?
EDIT: I have updated with the required code!!
this is the main() function
int main()
{
tree *tree=NULL; // all the confusion is regarding this
printf("hello"); // for debugging
//*tree->root=NULL; // tried this one but it was wrong
int value,choice;
while(1)
{
printf("enter the element : ");
scanf("%d",&value);
insert_iter(tree,value);
printf("do you want to enter more : 0 or 1 : ");
scanf("%d",&choice);
if(choice==0)
break;
}
return 0;
}
and this is the function that i used to insert the elements
void insert_iter(tree *tree, int data)
{
if(tree->root==NULL)
tree->root=newNode(data); // function to make a new node
else{
node *it=tree->root;
int dir;
while(1)
{
dir=data>it->data;
if(it->link[dir]!=NULL)
it=it->link[dir];
else
{
it->link[dir]=newNode(data);
break;
}
}}}
tree *tree=NULL; // all the confusion is regarding this
// the above is setting a pointer to NULL, which is ok
*tree->root=NULL; // tried this one but it was wrong
// the above is setting a
// (not initialized to point to any specific memory)
// offset in the tree struct variable
// (that offset is not pointing any specific memory)
// to set the first 4 bytes of that memory to NULL
// which should/will cause a seg fault event due to undefined behaviour
// a workable solution might be:
tree *pTree = malloc( sizeof(tree) );
// and then this would work:
tree->root = NULL; // notice no '*' dereference needed
//I would also strongly suggest that the variable names be different
//than the struct names, and not just in the capitalization of the name.
//The use of different names will greatly enhance
//the readability and understandability and clarity of the code
//(and will avoid any misunderstandings by the compiler and future maintainer)
Related
Hi guys I'm learning C programming. I wanted to write some codes for learning linked list topic but there is a problem. This code about creating linked list with 5 nodes, writing something into 3rd node, printing them to console.
Here is all of my codes:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
struct node{
char *data;
struct node *next;
};
typedef struct node node;
node *root;
void nodeAdd(node *n, int x)
{
node *iter;
iter=root;
for(int i=0;i<x;i++)
{
iter->next = (node*)malloc(sizeof(node));
iter->next->data="0";
iter->next->next=NULL;
iter=iter->next;
printf("Node created.\n");
}
}
void nodeWrite(node *n,char *string,int x)
{
node *temp;
temp=root;
for(int k=0;k<x;k++)
{
temp=temp->next;
}
strcpy(temp->data,string); //HERE IS ERROR
printf("\n");
printf("%s \n",temp->data);
printf("Node writed.");
}
void nodePrint(node *n)
{
while(root->next!=NULL)
printf("%s\n",root->data);
root=root->next;
}
int main(int argc, const char * argv[])
{
root = (node*)malloc(sizeof(node));
nodeAdd(root,5);
nodeWrite(root,"WTF", 3);
nodePrint(root);
return 0;
}
data is an unintialized pointer variable. Initialize with the address of a valid memory that you allocate. That will solve the problem. Now you have udnefined behavior.
What you can possibly do is
Use char array instead of using pointer.
Allocate dynamically the memory.
In case of 1.
struct node{
char data[MAXSTRINGLEN];
struct node *next;
};
In case of 2:
Initially make the pointers point to NULL. So now you can allocate to it like this
temp->data = malloc(sizeof *temp->data*MAXSTRINGLEN);
if( temp->data == NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
Just one point, free the allocated memory when you are done working with it.
Use of the global variable here is not really required here. You can always pass return pointers from memory and assign it to the struct node*. Or yes you can use double pointers. Use of global variable is not needed here.
Clean up code, that are redundant and not required. That makes things readable and less confusing.
The program initially is designed incorrectly and has undefined behavior..
For example the data member data of the node root was not initialized. So its output in the function nodePrint results in undefined behavior. Moreover the function itself is incorrect.
Neither function uses its parameter node *n.
In this statement
strcpy(temp->data,string);
there is an attempt to change the string literal pointed to by the data member temp->data provided that the data member was initialized (as it was pointed above the data member is not initialized for the node root). You may not change a string literal. Any attempt to modify a string literal leads to undefined behavior.
There is no need to declare the node root as a global variable.
Parameters of the function main are not used in the program. So the function should be declared like
int main( void )
the compiler stops working ,pls give me some solution
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
int data;
struct node *next;
}node;
node * create()
{
node *p;
p=malloc(sizeof(node));
p->next=NULL;
return p;
}
void add(node **h,int ele)
{ node *temp;
temp=(*h);
node *p=create();
while(temp->next!=temp)
temp=temp->next;
temp->next=p;
p->next=temp;
p->data=ele;
(*h)=temp;
}
void main()
{ int ch,ele;
node *h;
h->next=h;
do
{ printf("\n1 add 2 delete 3 insert at kth position 4 delete at kth position");
scanf("%d",&ch);
if(ch==1)
{
scanf("%d",&ele);
add(&h,ele);
}
//if(ch==2)
}while(ch!=5);
}
Like I said in my comment, my guess is that you have a crash, that the program stops when you run the program, and that it builds without errors.
The reason is that you are using the local non-static variable h without initializing it. All local non-static variables have an indeterminate value unless initialized, and using those variable without initialization leads to undefined behavior.
The solution is very simple: Allocate memory for a node (either as a normal variable or dynamically) and initialize the pointer h with that.
Most compilers are actually capable of detecting problems of this kind, but since it's syntactically and semantically legal it will not issue an error, but a warning instead. And if you don't get such a warning then you need to enable more warnings.
I am getting "cannot convert node** to node** error" for the given code.
Here both are node**.
Error is getting while the function insertintoBST is compared to its declaration.
node is a structure variable.
Here, I have tried to implement insertion into a binary search tree.
#include<stdio.h>
#include<conio.h>
void inserttoBST(struct node**,int,int);
void main()
{
int choice,i,j;
struct node{
int value;
int key;
struct node*left;
struct node*right;
};
struct node*root=NULL;
do{
printf("\n1.insert\n2.delete\n3.view list\n4.search");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("\nEnter the key and data :");
scanf("%d%d",&i,&j);
inserttoBST(&root,i,j);
break;
case 2: break;
case 3:break;
case 4:break;
default:printf("\nInvalid Entry");
}
}while(choice!=10);
}
void inserttoBST(struct node**root,int keys,int val)
{
if(*root==NULL)
{
struct node*nodes=(struct node*)malloc(sizeof(struct node));
nodes->key=key;
nodes->val=val;
nodes->left=nodes->right=NULL;
*root=nodes;
}
else if((*root)->key<keys)
inserttoBST((*root)->right,int keys,int val);
else inserttoBST((*root)->left,int keys,int val);
}
Your first problem is that struct node is not declared at the first point where you use it.
You need to move the definition out of main to before the inserttoBST prototype.
That's the first of many problems that code has, you also need to look at:
getting rid of conio.h, it's not a standard header.
including stdlib since that's needed for malloc.
figuring out whether your key variable should be key or keys.
figuring out whether your value structure field should be val or value.
getting rid of the int type specifiers from your calls to inserttoBST.
passing the correct value as the first argument to inserttoBST, specifically something like &((*root)->leftOrRight).
use int main (void) for the main function, this is one of the two canonical variants specifically allowed for by the standard.
That's everything I had to do to get it to compile, whether that's enough to remove any logic errors I couldn't say.
But, once you've got it to compile, that'll be the next step you need to take.
I have posted the link to my BST code on ideone: http://ideone.com/P7850n
In the main function I am getting an error when I read values in the while loop and insert into BST, but it works fine if I use a for loop. What could be the possible explanation for this error which occurs only with the while loop ?
#include <stdio.h>
#include <stdlib.h>
//data struct for BST node
typedef struct BST
{
int data;
struct BST *left;
struct BST *right;
}node;
//make node from given data
node* makeNode(int data)
{
node *n=(node*)malloc(sizeof(node));
n->data=data;
n->left=NULL;
n->right=NULL;
return n;
}
//insert node in BST
node* insert(node* root,int key)
{
if(root==NULL)
return makeNode(key);
if(key < root->data)
root->left=insert(root->left,key);
else
root->right=insert(root->right,key);
return root;
}
//inorder printing prints in sorted order
void inorder(node* root)
{
if(root==NULL)
return;
inorder(root->left);
printf("%d ",root->data);
inorder(root->right);
}
//driver function
int main(void) {
// your code goes here
node *root;
int s,i,key;
scanf("%d",&s);
while(s--)
//for(i=0;i<s;i++)
{
scanf("%d",&key);
root=insert(root,key);
}
inorder(root);
return 0;
}
Most probably this is an uninitialized variable root.
The compiler re-uses the same memory for variables, either declared in your program or used internally, after they are not anymore needed, so that other variables later occupy the same memory. In C (unlike, say, Perl), when memory is assigned to a variable, it is not automatically cleared: you should do it yourself, which is called initialization: typically as soon as you declare a variable, you should assign it some value: int year = 2014;. If you use a variable before you assign it a value, it's value will be whatever happens to be in memory that it occupies, left from other variables or even other running programs.
In your case, when you initialize the for loop with i=0, this 0 probably uses the memory later used for root, so accidentally it works. When you initialize the while loop with non-zero s, root uses memory that happens to be non-zero.
The solution is to initialize root = NULL;, and in general it's a good habit to always initialize all variables.
Without node *root = NULL; you are trying to access undefined memory address as root will contain any random data. So you can get valid behavior or any other behavior including crash.
As root is not initialized in inser() function if(root==NULL) may or may not be true and hence you will get different behavior.
This has nothing to do with for or while loop.
its always to initialize any memory variable to NULL or any other variable to 0,while writing any piece of code,otherwise you will always get any unpredictable crash or result.
like in this case,do like this below:
node *root;
int s,i,key;
to
node *root = NULL;
int s =0;
int i = 0;
int key= 0;
This is my First post on StackOverFlow.
I was working on linklist - below is my code.
I am just adding a single node to list and printing it -- All I am doing is passing a pointer to the "addTermNode" function and then pointing this passed pointer to the newly created Node.
#include<stdio.h>
#include<time.h>
typedef struct _termination_code_ {
int terminationCode;
unsigned long time;
struct _termination_code_ *next;
}termination_code;
int addTermCode(termination_code *infoTerm, int termCode, unsigned long timerInfo)
{
termination_code *node;
node=(termination_code*)malloc(sizeof(termination_code));
if(NULL == node) return -1;
node->terminationCode=termCode;
node->time=timerInfo;
node->next=NULL;
infoTerm = node;
return 0;
}
int main ()
{
termination_code *list2=NULL;
//Add A single node and print it.
if(addTermCode(list2, 12, time(0))==0)
printf("All OK node added\n");
else
printf("something went wrong\n");
printf("Entered info :%d %ld\n",list2->terminationCode,list2->time);
}
Here what I get the output -- Not sure why. Please Help.
[zahmed#build3 rnd]$ ./a.out
All OK node added
Segmentation fault
[zahmed#build3 rnd]$
Thanks
In addTermCode you are changing the value of the infoTerm variable. That value is a pointer, but you are only changing the local value (C is pass-by-value only). To change the pointer outside of the function, you should pass a pointer to the pointer... Something like termination_code **infoTerm, and change *infoTerm = &node.
And, to be clear, the segmentation fault is because you are accessing the outer pointer, which has not been changed and still points to the wrong address.
The problem is the way you are passing back the new object. Assigning the new object to the pointer will not work the way you have it written. You should return the object instead from your addTermCode() function.
Basically your list2 pointer is still null. Return the newly created object from that function and assign it to list2.
If not, you'll need to adjust your code so that the pointer is properly assigned.
int addTermCode(termination_code **infoTerm, int termCode, unsigned long timerInfo)
{
....
*infoTerm = node;
}
int main ()
{
termination_code *list2=NULL;
//Add A single node and print it.
if(addTermCode(&list2, 12, time(0))==0)
printf("All OK node added\n");
printf("Entered info :%d %ld\n",list2->terminationCode,list2->time);
}