Segmentation fault & core dump - core

I've been trying to code up binary tree by my own. It seems to be working until I want to scanf for new string to add. Same string works, new string gives me segmentation fault & core dump. I suspect there's something wrong with mallocing memory of new element.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//------- wezel -------//
struct node{
char *word;
unsigned int arity;
struct node *left, *right, *parent;
};
struct node *root;
/* Adding new string to tree */
void dopisz(char wordtmp[50], struct node *start){
if(root==NULL){ // empty tree, add as root
root=(struct node*)malloc(sizeof *root);
root->word=(char*)malloc(sizeof wordtmp);
root->word=strcpy(root->word, wordtmp);
root->arity=1;
root->left=NULL;
root->right=NULL;
root->parent=NULL;
}
else if(strcmp(wordtmp, start->word)==0){
start->arity=start->arity+1;
}
else if(strcmp(wordtmp, start->word)<0){ //if the added element is <
if(start->left==NULL){ //if there's no left son
struct node *nowy=(struct node*)malloc(sizeof *root);
nowy->word=strcpy(nowy->word, wordtmp);
nowy->arity=1;
nowy->left=NULL;
nowy->right=NULL;
nowy->parent=start;
start->left=nowy;
}
else if(start->left!=NULL){ //if there's left son
dopisz(wordtmp, start->left);
}
}
else if(strcmp(wordtmp, start->word)>0){ //if the added element is >
if(start->right==NULL){ //if there's no right son
struct node *nowy=(struct node*)malloc(sizeof *root);
nowy->word=strcpy(nowy->word, wordtmp);
nowy->arity=1;
nowy->left=NULL;
nowy->right=NULL;
nowy->parent=start;
start->right=nowy;
}
else if(start->right!=NULL){ //if there's right son
dopisz(wordtmp, start->right);
}
}
}
//-------looking for minimum -------//
struct node* least(struct node *start){
if(start->left != NULL){
return least(start->left);
}
else return start;
}
//------- deleting -------//
void usun(){
}
//------- printing -------//
void drukuj(struct node *start){ //printing in order in order
if(start->left!=NULL){
drukuj(start->left);
}
printf("%s (%d)\n", start->word, start->arity);
if(start->right!=NULL){
drukuj(start->right);
}
}
//------- main -------//
int main(){
char wordtmp[50];
printf("\t Drzewo Poszukiwan Binarnych \n------------------------\n\n");
int x, y=0;
while(y==0){
printf("\n MENU: \n 0 -> zakoncz \n 1 -> dopisz\n 2 -> usun\n 3 -> drukuj\n\n"); // 0 - exit, 1 - add, 2 - delete, 3 - print
scanf("%d", &x);
switch(x){
case 0: y++; break;
case 1:
printf("wpisz slowo: ");
scanf("%s", wordtmp);
dopisz(wordtmp, root);
break;
case 2: usun(); break;
case 3: drukuj(root); break;
}
}
return 0;
}

The line
nowy->word=strcpy(nowy->word, wordtmp);
is wrong. nowy->word doesn't have any storage points to arbitrary memory. Copying a string to it has undefined results but a seg fault is likely.
You can fix this by making word a fixed size array in node's definition or by allocating memory for it dynamically
nowy->word=malloc(strlen(wordtmp)+1);
strcpy(nowy->word, wordtmp);
or
nowy->word=strdup(wordtmp); // not standard C but available in Posix systems

Related

scanf() running endlessly, program stops running on a statement

This is the code for BFT(breadth first traversal) for a connected graph.
I run the code then I successfully make the adjacency list and also successfully print the adjacency list but after it program stops at when I take input from user to start the BFS from that inputed node.
scanf() is running infinitely or other error I can't able to identify.
#include<stdio.h>
#include<stdlib.h>
typedef struct root //the adjacency list which have all the vertices
{
int info;
struct adjacent *adj;
struct root *next;
} root;
typedef struct adjacent //Linked list which store adjacent nodes of any nodes in adj list.
{
int info;
struct adjacent *adj;
} adjacent;
typedef struct node // to make queue to store nodes to be explored.
{
int info;
struct node *next;
} nodeQ;
void insert(nodeQ **ft,nodeQ **rr,int n) // insert func of Q
{
nodeQ * new=(nodeQ *)malloc(sizeof(nodeQ));
new->info = n;
new->next = NULL;
if(*ft == NULL)
{
*ft=new;
*rr=new;
}
else
{
(*rr)->next = new;
*rr = new;
}
}
int delete(nodeQ **ft,nodeQ **rr) //delete func of Q
{
int value=(*ft)->info;
nodeQ *temp=*ft;
*ft=(*ft)->next;
free(temp);
if(*ft==NULL)
*rr=NULL;
return value;
}
void BFS(int total_nodes,int node_tobe_explored,root *head,nodeQ **ft,nodeQ **rr)
{
printf("ff");
int * visited=(int *)malloc(sizeof(int)*total_nodes);
for(int i=0;i<total_nodes;i++)
visited[i]=0; //initialize all value in visited array with 0
printf("aa");
visited[node_tobe_explored] = 1;
printf("%d",node_tobe_explored);
while(1) // this loop iterates until all nodes are not explored.
{
root *t=head;
while(t->info != node_tobe_explored) // this find the node address(t) of the node_tobe_explored.
t=t->next;
printf("bb");
adjacent * adj_node = t->adj;
while(adj_node)
{
if(visited[adj_node->info] == 0) //if that adjacent node is not visited then also we visit it.
{
int adj_node_val = adj_node->info;
visited[adj_node_val] = 1;
insert(ft,rr,adj_node_val);
printf(", %d",adj_node_val);
}
}
printf("cc");
if(*rr==NULL) //if Q is empty, means all nodes are explored, so we return.
return;
else //otherwise explore first node present in Q
node_tobe_explored = delete(ft,rr);
}
}
int main()
{
char ch;
int no,tot_nodes,start;
nodeQ *front=NULL,*rear=NULL;
printf("enter the no. of nodes: ");
scanf("%d",&tot_nodes);
root *head = NULL;
no = tot_nodes;
while(no!=0)
{ //to make the main chain of adjacency list.
root *new=(root *)malloc(sizeof(root));
new->info = no;
new->adj = NULL;
new->next = head;
head = new;
no--;
}
root *temp = head;
while(temp!=NULL)
{ // to add the adjacent nodes to main chain.
printf("enter the nodes adjacent to %d:\n",temp->info);
do
{
int element;
printf(" enter node: ");
scanf("%d",&element);
adjacent *nw = (adjacent *)malloc(sizeof(adjacent));
nw->info = element;
nw->adj = temp->adj;
temp->adj = nw;
printf("more adjacent nodes y/n: ");
ch=getchar();
ch=getchar();
}while(ch=='Y'||ch=='y');
temp=temp->next;
}
printf("display of the structur of the linked list formed:\n");
root * head1=head;
while(head1) // to display the formed adj. list.
{
printf("%d--",head1->info);
adjacent *t = head1->adj;
while(t)
{
printf("%d,",t->info);
t=t->adj;
}
printf("\n");
head1=head1->next;
}
do
{
printf("enter the node value from which you want to start BFS: ");
printf("before [enter image description here][1]");
int st;
scanf("%d",&st);
printf("after");
BFS(tot_nodes,st,head,&front,&rear); //calling BFS func.
printf("do you want to print more traversals y/n: ");
ch=getchar();
ch=getchar();
}while(ch=='Y'||ch=='y');
}
Excerpt from OPs source code:
printf("do you want to print more traversals y/n: ");
ch=getchar();
ch=getchar();
}while(ch=='Y'||ch=='y');
The intention was probably to read a letter (y or n) and the \n which confirmed the input.
So, the 2nd ch=getchar(); (for ENTER) overrides the previously read letter. The following fix would change this:
printf("do you want to print more traversals y/n: ");
ch=getchar();
getchar(); /* ignore the returned value - it's just to consume '\n'. */
}while(ch=='Y'||ch=='y');
Btw. this is something which should have been uncovered by a step-wise debugging of the cited four lines...

Single linkedlist creation in C

#include<stdio.h>
#include<stdlib.h>
struct list
{
int a;
int b;
int c;
struct list *next;
};
struct list* addlistele(struct list*,int,int,int);
/* List c element */
void listc()
{
printf(" soon...\n");
}
void printlist(list)
{
struct list* temp;
temp=list;
while(temp!=NULL)
{
printf("a:%d,b;%d,c:%d\n",temp->a,temp->b,temp->c);
temp=temp->next;
}
}
/* List element */
struct list* addlistele(struct list* listadd,int b,int d,int m)
{
int i;
struct list* temp;
struct list* addelement=(struct list*)malloc(sizeof(struct list));
addelement->a=b;
addelement->b=d;
addelement->c=m;
addelement->next=NULL;
if(listadd==NULL)
{
printf("entering");
return addelement;
}
else
{
temp=listadd;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=addelement;
}
return listadd;
}
int main()
{
int ch,i,a,b,c;
struct list *element,*list;
element=(struct list*)malloc(sizeof(struct list));
printf("Choose any one of the option \n");
printf("1.List All \n 2.List c \n");
scanf("%d",&ch);
switch(ch)
{
case 1:printf("Enter values \n");
for(i=0;i<2;i++)
{
scanf("%d %d %d \n",&a,&b,&c);
list=addlistele(element,a,b,c);
}
printlist(list);
break;
case 2:listc(); break;
default:break;
}
}
Hi all, i have written the code like the above one.In that when i gave inputs
> Choose any one of the option
> 1.List All
> 2.List c 1 Enter values 2 3 4 1 2 3
The output is
a:0,b;0,c:0
a:2,b;3,c:4
a:1,b;2,c:3
and also it is not adding the element first i mean it is not entering into this loop
if(listadd==NULL)
{
printf("entering");
return addelement;
}
how to make the head element to be NULL and also i don't know how 0 is coming first.Could anybody can tell me what will be the issue?
In main() you create head element and pass it to the addlistele() function.
element=(struct list*)malloc(sizeof(struct list));
...
list=addlistele(element,a,b,c);
You are seeing this first element which does not have valid values that you expected.
Solution would be you malloc() the element in the function rather than in main() and do not allocate element in main().
replace
struct list *element,*list;
element=(struct list*)malloc(sizeof(struct list));
with
struct list *list=NULL;
then
replace
list=addlistele(element,a,b,c);
with
list=addlistele(list,a,b,c);
Also
replace
void printlist(list)
with
void printlist(struct list *list)
and
replace scanf("%d %d %d \n",&a,&b,&c); with scanf("%d %d %d",&a,&b,&c);

Memory allocation to a Node with Character array in a Linked list

OK, this is a simple single linked list program in c
struct node
{
int id;
char name[20];
int sem;
struct node *link;
};
typedef struct node* Node;
Node getnode()
{
Node temp=(Node)(malloc(sizeof(Node)));
if(temp==NULL)
printf("\n Out of memory");
return temp;
}
Node ins_pos(Node first)
{
Node temp=getnode();
printf("\n Enter id ");
scanf("%d",&temp->id);
printf("\n Enter name ");
scanf("%s",temp->name);
printf("\n Enter semester ");
scanf("%d",&temp->sem);
if(first == NULL)
{
temp->link=NULL;
return temp;
}
else
{
int pos,i;
printf("\n Enter position: ");
scanf("%d",&pos);
if(pos == 1)
{
temp->link=first;
return temp;
}
else
{
Node prev=NULL,cur=first;
for(i=1; i<pos; i++)
{
if(cur==NULL)
break;
prev=cur;
cur=cur->link;
}
if(cur==NULL && i < pos)
printf("\n Position invalid");
else
{
prev->link=temp;
temp->link=cur;
}
return first;
}
}
}
Node del(Node first)
{
if(first==NULL)
printf("\n List is Empty ");
else
{
Node temp=first;
printf("\n ID: %d was deleted",temp->id);
first=first->link;
free(temp);
}
return first;
}
void disply(Node first)
{
if(first==NULL)
printf("\n List is empty");
else
{
Node cur=first;
while(cur!=NULL)
{
printf("\n ID : ");
printf("%d",cur->id);
printf("\n Name : ");
printf("%s",cur->name);
printf("\n Semester : ");
printf("%d",cur->sem);
printf("\n\n\n");
cur=cur->link;
}
}
}
int main()
{
Node first=NULL;
int opt;
do
{
printf("\n QUEUE MENU\n 1.Insert at position \n 2.delete front\n 3.display\n 4.Exit \n\n Enter your choice : ");
scanf("%d",&opt);
switch(opt)
{
case 1 :first = ins_pos(first);
break;
case 2 :first = del(first);
break;
case 3 :disply(first);
break;
}
}while(opt!=4);
return 0;
}
When inserting a new node, Code Blocks Crashes at the malloc statement. How do I know? well, it crashes before asking "Enter ID". So, am I doing something wrong?
Another point here is, it works fine with only an integer field in node, the problem here maybe the character array.
In this function Node getnode() -
Node temp=(Node)(malloc(sizeof(Node)));
With the above malloc you allocate memory equal to size of Node which is of type struct pointer , and is not enough .Therefore ,you get a segmentation fault.
instead of this ,write like this -
Node temp=malloc(sizeof(*temp)); //also there is no need of cast
This will allocate memory equal to size of type to which temp points to i.e size equal to that of structure. Which is appropriate .
Some errors here.
malloc( sizeof( struct node ) );
Otherwise too little memory is allocated.
Do you include stdlib.h for malloc definition - that would cause this issue (no definition, defaults to int).
You need to use Node temp=(Node)(malloc(sizeof(*temp)));

Why the address returned by the create function is not same as root for the first node

Below is my code for the BST :
insert works fine but search doesnt
typedef struct tree_node{
struct tree_node* parent;
struct tree_node* left;
struct tree_node* right;
int x;
}tree_node;
tree_node *strt=NULL;
tree_node *traverse;
tree_node* create(int info){
tree_node *temp=NULL;
temp=(tree_node*)malloc(sizeof(tree_node));
temp->parent=NULL;
temp->left=NULL;
temp->right=NULL;
temp->x=info;
return temp;
}
tree_node* insert(tree_node *root, int a){
/* here i am printing the address of the node which must be same as the root for the first node */
if(root==NULL){
printf("%d ",create(a));
return create(a);
}
else if(a <= root->x)
return insert(root->left,a);
else
return insert(root->right,a);
return root;
}
tree_node* search_ele(tree_node *root,int info){
if(root==NULL || root->x==info)
return root ;
if(info < root->x)
return search_ele(root->left,info);
else
return search_ele(root->right,info);
}
void display_inorder(tree_node *root){
if(root==NULL)
return;
display_inorder(root->left);
printf("%d ",root->x);
display_inorder(root->right);
}
void main(){
int element;
tree_node *search_element;
while(1){
char ch;
int num;
printf("\nWant to enter a node..??\n\n");
scanf(" %c",&ch);
if(ch=='n'||ch=='N')
break;
else{
printf("Enter the number \n");
scanf("%d",&num);
if(strt==NULL)
printf("Tree is empty...entering first node...!!!\n");
strt=insert(strt,num);
printf("%d",strt);
}
}
printf("Enter the element u want to search\n");
scanf("%d ",&element);
if(search_ele(strt,element)==NULL)
printf("no such element\n");
else
printf("element found\n");
display_inorder(strt);
}
The output displays :
Want to enter a node ?
y
Enter the number
6
Tree is empty...entering first node...!!!
5279480 5279504 (why are these different??)
You print the result of calling create, and then call create again for the return value, thus creating a second node.
First the problems with your BST Algorithm: Your node creation algorithm never attaches new nodes to a parent. Create() sets node->parent to NULL and your insert() never updates the parent variable to root. Additionally, you're never setting the new left/right fields of your new node's parent
Change
return create(a)
to
tree_node * new_node = create(a);
new_node->parent=root;
new_node->parent->left/right=new_node; //include some way to distinguish whether you went left or right in the previous recursive call
return new_node
Now for your address question, you call create() twice, which (think procedurally) results in two malloc() calls, and thus two addresses.

C Program to copy one binary search tree to another

So, here i have come up with Binary search tree prgram, where i am creating 2 binary trees tmp and tmp2, where i am trying to copy whole tmp2 to tmp, the node which is taken as input from user. But i am getting some segmentation fault, also i am not so sure if the logic is right.
Here is the whole program, please lemme know where is it going wrong in t_cpy() or please just fix it for me..
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *rlink;
struct node *llink;
}*tmp=NULL,*tmp2=NULL,*tmp3=NULL;
typedef struct node NODE;
NODE *create();
void inorder(NODE *);
void insert(NODE *);
void t_cpy(NODE *,NODE *);
int main()
{
int n,m;
do
{
printf("\n1.create tree 1\n2.Insert element to tree1\n3.create tree 2\n4.Insert element to tree2\n5.Inorder tree1\n6.Inorder tree2\n7.Copy tree2 to tree1\n8.exit\n\n");
printf("\nEnter ur choice: ");
scanf("%d",&m);
switch(m)
{
case 1: tmp=create();
break;
case 2: insert(tmp);
break;
case 3: tmp2=create();
break;
case 4:
insert(tmp2);
break;
case 5: printf("\n\nInorder Tree1: ");
inorder(tmp);
break;
case 6: printf("\n\nInorder Tree 2: ");
inorder(tmp2);
break;
case 7: t_cpy(tmp,tmp2);
break;
case 8: return(0);
}
}while(n!=8);
return(0);
}
void insert(NODE *root)
{
NODE *newnode;
if(root==NULL)
{
newnode=create();
root=newnode;
}
else
{
newnode=create();
while(1)
{
if(newnode->data<root->data)
{
if(root->llink==NULL)
{
root->llink=newnode;
break;
}
root=root->llink;
}
if(newnode->data>root->data)
{
if(root->rlink==NULL)
{
root->rlink=newnode;
break;
}
root=root->rlink;
}
}
}
}
NODE *create()
{
NODE *newnode;
int n;
newnode=(NODE *)malloc(sizeof(NODE));
printf("\n\nEnter the Data ");
scanf("%d",&n);
newnode->data=n;
newnode->llink=NULL;
newnode->rlink=NULL;
return(newnode);
}
void t_cpy(NODE *t1,NODE *t2)
{
int val,opt=0;
NODE *temp;
if(t1==NULL || t2==NULL)
{
printf("Can not copy !\n");
}
inorder(t1);
printf("\nEnter the node value where tree 2 should be copied\n");
scanf("%d",&val);
temp=t1;
while(temp!=NULL)
{
if(val<temp->data)
temp=temp->llink;
else
temp=temp->rlink;
}
if(temp->llink!=NULL || temp->rlink!=NULL)
printf("Not possible to copy tree to this node\n");
else
{
printf("Copy tree to \n 1.Left Node \n 2.Right Node\n Enter your choice : ");
scanf("%d",&opt);
if(opt==1)
{
temp->llink=t2;
}
else if(opt==2)
{
temp->rlink=t2;
}
else
printf("Invalid choice\n");
}
printf("Tree1 after copying is\n");
inorder(temp);
}
void inorder(NODE *tmp)
{
if(tmp!=NULL)
{
inorder(tmp->llink);
printf("%d",tmp->data);
inorder(tmp->rlink);
}
}
EDIT : Thanks to #xaxxon , who helped me with this.
Just update the while to make it work :
while(temp!=NULL&&temp->data!=val)
{
if(val<temp->data)
temp=temp->llink;
else
temp=temp->rlink;
if(temp->llink==NULL && temp->rlink==NULL && temp->data!=val)
{
printf("Invalid Node value entered !\n");
//break;
return 0;
}
and, Now it works fine for if entered value is present in the tree.
Thanks :)
Among other possible problems, you traverse temp until it is null, and on the next line you dereference it.
while(temp!=NULL)
{
if(val<temp->data)
temp=temp->llink;
else
temp=temp->rlink;
}
if(temp->llink!=NULL || temp->rlink!=NULL)
printf("Not possible to copy tree to this node\n");
You most likely mean to break out of this loop if val == temp->data, but you don't. Also, you still need to check to see if temp is null after the loop in case you didn't find val in your tree. Most likely you just meant to say:
if(temp==NULL)
printf("Not possible to copy tree to this node\n");
Also, you can't ask which side of the found node the user wants to copy a tree to. If you have a binary search tree, it has to be the side where the value should go. If you say to copy it to the right side, but all the values are less than the node, it's no longer a BST. In fact, you can't even ask where the value should go and still have a binary search tree. Each node has to be traversed from the root of the tree you want to put the other tree into to maintain the BST mechanics.
When you first use insert(tmp) the value of tmp does not change after you call insert(). Pass the address of tmp to insert(), using a *root within it instead of root.

Resources