How to fix my assign program with runtime error - c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct listnode
{
int data;
struct listnode *nextptr;
struct listnode *prevptr;
}*head,*tail;
void print_linked_list(){
struct listnode *temp;
temp=head;
while(temp!=NULL){
printf("%d ",temp->data);
temp = temp->nextptr;
}
}
void InsertAtHead(int x){
struct listnode *var,*temp;
var=(struct listnode *)malloc(sizeof(struct listnode));
var->data=x;
if(head==NULL){
head = var;
head->prevptr=NULL;
head->nextptr=NULL;
tail=head;
}
else{
temp=var;
temp->prevptr=NULL;
temp->nextptr=head;
head->prevptr=temp;
head=temp;
}
}
void InsertAtTail(int x) {
struct listnode *var,*temp;
var=(struct listnode *)malloc(sizeof(struct listnode));
var->data=x;
if(head==NULL){
head=var;
head->prevptr=NULL;
head->nextptr=NULL;
tail=head;
}
else{
tail=head;
while(tail!=NULL){
temp=tail;
tail=tail->nextptr;
}
tail=var;
temp->nextptr=tail;
tail->prevptr=temp;
tail->nextptr=NULL;
}
}
int DeleteAtHead(){
struct listnode* temp;
temp=head;
if(temp->nextptr==NULL){
free(temp);
head=NULL;
tail=NULL;
return 0;
}
head=temp->nextptr;
head->prevptr=NULL;
free(temp);
return 0;
}
int DeleteAtTail(){
struct listnode* temp;
temp=tail;
if(temp->prevptr==NULL){
free(temp);
head=NULL;
tail=NULL;
return 0;
}
tail=temp->prevptr;
tail->nextptr=NULL;
free(temp);
return 0;
}
int main(){
head=NULL;
char operation[10];
char place[5];
int element;
/** write code here ^-^ya **/
while(scanf("%s ",operation)!=EOF){
if(strcmp(operation,"insert")==0){
scanf("%s",place);
if(strcmp(place,"head")==0){
scanf("%d",&element);
InsertAtHead(element);
}
else if(strcmp(place,"tail")==0){
scanf("%d",&element);
InsertAtTail(element);
}
}
else if(strcmp(operation,"delete")==0){
scanf("%s",place);
if(strcmp(place,"head")==0){
DeleteAtHead();
}
else if(strcmp(place,"tail")==0){
DeleteAtTail();
}
}
}
print_linked_list();
printf ("\n");
return 0;
}
When I submit my code,it always appears Runtime Error(RE) and Time limit Exceeded(TLE).
I try to free some memory but useless. How can I solve this?

Related

Why am I not getting the last print statement, unable to get height of the tree?

After taking values for nodes, program terminates. I don't know what I am doing wrong. I don't even know if the values are getting inserted.
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
struct Node* GetNode(int data){
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->data=data;
newnode->left = NULL;
newnode->right = NULL;
}
struct Node* insert(struct Node* root,int data){
if(root=NULL){
root = GetNode(data);
return root;
}
else if(data <= root->data){
root->left = insert(root->left,data);
}
else{
root->right = insert(root->right,data);
}
return root;
}
int height(struct Node* root){
if(root==NULL){
return 0;
}
else{
int lh = height(root->left);
int rh = height(root->right);
if(lh>rh){
return (lh+1);
}
else{
return (rh+1);
}
}
}
int main() {
struct Node* root =NULL;
int n,i;
printf("Enter the total number of nodes in the tree: ");
scanf("%d",&n);
int value[n];
for(i=0;i<n;i++){
printf("Enter the %d node ",i+1);
scanf("%d",&value[i]);
}
for(i=0;i<n;i++){
root = insert(root,value[i]);
}
int high = height(root);
printf("Height of the given tree is : %d ",high);
return 0;
}
No, idea if it is the height function or the insert function.
You have 2 problems in your code.
In the function struct Node* GetNode(int data), you are not returning the newnode.
In the function struct Node* insert(struct Node* root,int data), in the if condition if(root=NULL), you should use ==
Here is the corrected working code:
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
struct Node* GetNode(int data){
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->data=data;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
struct Node* insert(struct Node* root,int data){
if(root==NULL){
root = GetNode(data);
return root;
}
else if(data <= root->data){
root->left = insert(root->left,data);
}
else{
root->right = insert(root->right,data);
}
return root;
}
int height(struct Node* root){
if(root==NULL){
return 0;
}
else{
int lh = height(root->left);
int rh = height(root->right);
if(lh>rh){
return (lh+1);
}
else{
return (rh+1);
}
}
}
int main() {
struct Node* root =NULL;
int n,i;
printf("Enter the total number of nodes in the tree: ");
scanf("%d",&n);
int value[n];
for(i=0;i<n;i++){
printf("Enter the %d node ",i+1);
scanf("%d",&value[i]);
}
for(i=0;i<n;i++){
root = insert(root, value[i]);
}
int high = height(root);
printf("Height of the given tree is : %d ",high);
return 0;
}

Free malloc, using Linus method of deletion in a linked list

I been stuck in this problem for hours and I still cannot free the malloc of my program. for some reason it says I have 16 bytes in 1 blocks, I have been trying to free the malloc using a function freeList() in the program but it seems to not be working, if you can catch what is my error I will really appreciate it!
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
}*head;
void append(int num)
{
struct node *temp,*right;
temp= (struct node *)malloc(sizeof(struct node));
temp->data=num;
right=(struct node *)head;
while(right->next != NULL)
right=right->next;
right->next =temp;
right=temp;
right->next=NULL;
}
void add( int num )
{
struct node *temp;
temp=(struct node *)malloc(sizeof(struct node)); //*
temp->data=num;
if (head== NULL)
{
head=temp;
head->next=NULL;
}
else
{
temp->next=head;
head=temp;
}
}
void addafter(int num, int loc)
{
int i;
struct node *temp,*left,*right;
right=head;
for(i=1;i<loc;i++)
{
left=right;
right=right->next;
}
temp=(struct node *)malloc(sizeof(struct node));
temp->data=num;
left->next=temp;
left=temp;
left->next=right;
return;
}
void insert(int num)
{
int c=0;
struct node *temp;
temp=head;
if(temp==NULL)
{
add(num);
}
else
{
while(temp!=NULL)
{
if(temp->data<num)
c++;
temp=temp->next;
}
if(c==0)
add(num);
else if(c<count())
addafter(num,++c);
else
append(num);
}
}
int delete(int num)
{
struct node **temp;
temp=&head;
while(*temp!=NULL)
{
if((*temp)->data==num)
{
*temp= (*temp)->next;
return 1;
}
else
{
*temp= &((*temp)->next);
}
}
return 0;
}
void freeList(){
struct node *temp;
int i=0;
while(head!=NULL){
temp=head;
head=head->next;
free(temp->data);
free(temp);
i++;
}
printf("free %d records...\n",i);
}
void display(struct node *r)
{
r=head;
if(r==NULL)
{
return;
}
while(r!=NULL)
{
printf("%d ",r->data);
r=r->next;
}
printf("\n");
}
int count()
{
struct node *n;
int c=0;
n=head;
while(n!=NULL)
{
n=n->next;
c++;
}
return c;
}
int main()
{
int i,num;
struct node *n;
head=NULL;
while(1)
{
printf("\nList Operations\n");
printf("===============\n");
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Size\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
if(scanf("%d",&i)<=0){
printf("Enter only an Integer\n");
exit(0);
} else {
switch(i)
{
case 1: printf("Enter the number to insert : ");
scanf("%d",&num);
insert(num);//*
break;
case 2: if(head==NULL)
{
printf("List is Empty\n");
}
else
{
printf("Element(s) in the list are : ");
}
display(n);
break;
case 3: printf("Size of the list is %d\n",count());
break;
case 4: if(head==NULL)
printf("List is Empty\n");
else{
printf("Enter the number to delete : ");
scanf("%d",&num);
if(delete(num))
printf("%d deleted successfully\n",num);
else
printf("%d not found in the list\n",num);
}
break;
case 5: freeList();
return 0;
default: printf("Invalid option\n");
}
}
}
return 0;
}
My main problem is in the function freeList() when running the code freeList does not free the malloc.
void freeList(){
struct node *temp;
int i=0;
while(head!=NULL){
temp=head;
head=head->next;
free(temp->data);
free(temp);
i++;
}
printf("free %d records...\n",i);
}

Implementation of a stack using a circular double linked list

I want to implement a stack using a circular double linked list.
typedef struct node{
int data;
struct node *next,*prev;
}cdllnode;
cdllnode* createcdllnode(int data){
cdllnode* newnode=(cdllnode*)malloc(sizeof(cdllnode));
newnode->data=data;
newnode->next=NULL;
newnode->prev=NULL;
return newnode;
}
cdllnode* push(cdllnode *head,cdllnode *tos,int data){
cdllnode *newnode = createcdllnode(data);
if(head==NULL){
head=newnode;
tos=head;
}
else{
tos->next=newnode;
newnode->prev=tos;
tos=newnode;
tos->next=head;
head->prev=tos;
}
return head;
}
int pop(cdllnode *head,cdllnode *tos){
if(head==NULL){
printf("Empty Stack!\n");
return INT_MIN;
}
int temp= tos->data;
tos=tos->prev;
tos->next=head;
head->prev=tos;
return temp;
}
void printstack(cdllnode *head,cdllnode *tos){
if(head==NULL){
printf("Empty Stack!\n");
return ;
}
cdllnode *p=tos;
do{
printf("%d\n",p->data);
p=p->prev;
}while(p!=tos);
}
I'm able to push the first element but if I try inserting any element after that,I'm getting a segmentation fault.
Same is the case with the pop and printstack function.
EDIT
I corrected my code. It was unnecessary to use two pointers to access the list.This code works perfectly fine.
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
typedef struct dnode{
int data;
struct dnode *next,*prev;
}cdllnode;
cdllnode* createcdllnode(int data){
cdllnode* newnode=(cdllnode*)malloc(sizeof(cdllnode));
newnode->data=data;
newnode->next=NULL;
newnode->prev=NULL;
return newnode;
}
cdllnode* push(cdllnode *head,int data){
cdllnode *newnode = createcdllnode(data);
if(head==NULL){
head=newnode;
}
else if(head->next==NULL){
head->next=newnode;
newnode->prev=head;
newnode->next=head;
head->prev=newnode;
}
else{
cdllnode *p = head;
p=head->prev;
p->next=newnode;
newnode->prev=p;
newnode->next=head;
head->prev=newnode;
}
return head;
}
cdllnode* pop(cdllnode *head,int *temp){
if(head==NULL){
printf("Empty Stack!\n");
*temp= INT_MIN;
return head;
}
if(head->next==head){
*temp=head->data;
head=NULL;
}
else{
cdllnode *p=head->prev;
*temp= p->data;
p=p->prev;
p->next=head;
head->prev=p;
}
return head;
}
void printstack(cdllnode *head){
if(head==NULL){
printf("Empty Stack!\n");
return ;
}
cdllnode *p=head;
do{
if(p->next== head){
printf("%d\n",p->data);
}
else{
printf("%d->",p->data);
}
p=p->next;
}while(p!=head);
}
int main(){
cdllnode *head=NULL;
int choice,ele;
do{
printf("1.PUSH\t2.POP\t3.PRINT\t4.EXIT\n");
scanf("%d",&choice);
switch(choice){
case 1 :{
printf("Enter an element.\n");
scanf("%d",&ele);
head=push(head,ele);
printf("Element Added!\n");
break;
}
case 2:{
head=pop(head,&ele);
if(ele!= INT_MIN){
printf("Popped %d from the stack.\n",ele);
break;
}
}
case 3:{
printstack(head);
break;
}
case 4:{
break;
}
default : {
choice=4;
break;
}
}
}while(choice!=4);
}

segmenation fault error in my linkedList -C

I put together a few pieces of code to make a linked list that adds to head(Has a special function) and in the middle(also special function).
my problem is, i need to provide the program with numbers and insert them as nodes in my LINKEDLIST. However, my display function(to display the tree of nodes) gives back segmentation fault and so does just taking values in without any display function.
I'm fairly new to malloc so i suspect the problem is there?
Thanks
#include<stdio.h>
#include<stdlib.h>
/*LINKEDLIST STRUCT*/
struct node {
int data;
struct node *next;
};
/*Inserting head-Node*/
struct node *insert_head(struct node *head, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = head;
head = temp;
return head;
}
/*Inserting inside a list*/
void after_me(struct node *me, int number)
{
struct node *temp;
temp = malloc(sizeof(struct node));
if(temp == NULL)
{
printf("Not enough memory\n");
exit(1);
}
temp->data = number;
temp->next = me->next;
me->next = temp;
}
/*PRINTING LIST*/
void display(struct node *head)
{
struct node *moving_ptr = head;
while(moving_ptr != NULL)
{
printf("%d-->",moving_ptr->data);
moving_ptr = moving_ptr->next;
}
}
int main()
{
int index;
struct node *head;
struct node *previous_node;
scanf("%d", &index);
while(index > 0)
{
/*allocating in List */
if(head == NULL)
head = insert_head(head,index);
else
if((head != NULL) && (index <= (head->data)))
{
struct node *temp;
head->next = temp;
temp->next = head;/*TRY INSERT HEAD FUNC.*/
}
else
if((head != NULL) && (index > (head->data)))
{
previous_node->data = index-1;
after_me(previous_node,index);
}
scanf("%d", &index);
}
display(head);
}
I suggest as follows.
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *next;
};
//aggregated into one place
struct node *new_node(int number){
struct node *temp;
if(NULL == (temp = malloc(sizeof(*temp)))){
printf("\nNot enough memory\n");
exit(1);
}
temp->data = number;
temp->next = NULL;
return temp;
}
struct node *insert_head(struct node *head, int number) {
struct node *temp = new_node(number);
temp->next = head;
return temp;
}
void after_me(struct node *me, int number){
struct node *temp = new_node(number);
temp->next = me->next;
me->next = temp;
}
void display(struct node *head){
struct node *moving_ptr = head;
while(moving_ptr != NULL){
printf("%d", moving_ptr->data);
if(moving_ptr = moving_ptr->next)
printf("-->");
}
putchar('\n');
}
struct node *insert(struct node *me, int number){
if(me){
if(number <= me->data){
me = insert_head(me, number);
} else {
me->next = insert(me->next, number);
}
} else {
me = new_node(number);
}
return me;
}
void release(struct node *list){//Of course, you will be able to replace a simple loop(e.g while-loop).
if(list){
release(list->next);
free(list);
}
}
int main(void){
struct node *head = NULL;
int index;
while(1==scanf("%d", &index) && index > 0){
head = insert(head, index);
}
display(head);
release(head);
return 0;
}

segmentation fault with linked list

Please see this program given below. It crashes at the end of delete_node function. Please let me know what is going wrong. It crashes at the end of delete_node(5) call. printf statement after call to delete_node is not executed.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
typedef struct _list{
int data;
struct _list *next;
}list;
list* create_list(int val);
list* add_list(int val, bool ad_end);
int delete_node(int val);
void print_list(void);
list* head = NULL;
list* curr = NULL;
int main()
{
int val = 10;
list* mylist;
mylist = create_list(5);
add_list(val, true);
add_list(20, true);
add_list(30, true);
add_list(25, true);
print_list();
delete_node(5);
printf("\n I am here in main \n");
print_list();
return 0;
}
list* create_list(int val)
{
list* ptr =(list*) malloc(sizeof(list));
head = curr = ptr;
ptr->data = val;
ptr->next = NULL;
return ptr;
}
list* add_list(int val, bool add_end)
{
list* ptr =(list*) malloc(sizeof(list));
ptr->data = val;
ptr->next = NULL;
if(add_end) {
curr->next = ptr;
curr = ptr;
} else {
ptr->next = head;
head = ptr;
}
return ptr;
}
int delete_node(int val)
{
list* tmp = NULL;
list* prev;
tmp = head;
while(tmp){
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
prev->next = tmp->next;
if( tmp == head) {
head = tmp->next;
}
free(tmp);
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
break;
} else {
prev = tmp;
tmp = tmp->next;
}
printf("Node to be deleted not found \n");
}
return 1;
}
void print_list(void)
{
list* tmp = head;
while(tmp != NULL) {
printf("addr %p\t addr next %p\n", tmp, tmp->next);
printf(" Data is %d \n", tmp->data);
tmp = tmp->next;
}
printf("\n");
}
Here is your code after correction it is working absolutely fine now, by the way this is not a good way of making the linked list.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
typedef struct _list{
int data;
struct _list *next;
}list;
list* create_list(int val);
list* add_list(int val, bool ad_end);
int delete_node(int val);
void print_list(void);
list* head = NULL;
list* curr = NULL;
int main()
{
int val = 10;
list* mylist;
mylist = create_list(5);
add_list(val, true);
add_list(20, true);
add_list(30, true);
add_list(25, true);
print_list();
delete_node(5);
printf("\n I am here in main \n");
print_list();
return 0;
}
list* create_list(int val)
{
list* ptr =(list*) malloc(sizeof(list));
head = curr = ptr;
ptr->data = val;
ptr->next = NULL;
return ptr;
}
list* add_list(int val, bool add_end)
{
list* ptr =(list*) malloc(sizeof(list));
ptr->data = val;
ptr->next = NULL;
if(add_end&&head!=NULL) {
while(curr->next!=NULL){
curr= curr->next;
}
curr->next=ptr;
curr = ptr;
} else {
ptr->next = head;
head = ptr;
}
return ptr;
}
int delete_node(int val)
{
list* tmp = NULL;
list* prev;
tmp = head;
while(tmp->next!=NULL){
prev=tmp;
if( tmp == head&&head->next!=NULL) {
head = tmp->next;
free(tmp);
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
break;
}
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
tmp=tmp->next;
prev->next=tmp->next;
free(tmp);
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
break;
} else{
printf("Node to be deleted not found \n");
}
}
return 1;
}
void print_list(void)
{
list* tmp = head;
while(tmp != NULL) {
printf("addr %p\t addr next %p\n", tmp, tmp->next);
printf(" Data is %d \n", tmp->data);
tmp = tmp->next;
}
printf("\n");
}
Kindly go through this linked list implemented by me, which I believe will be much simpler to understand and code
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct node{
char data;
struct node *next;
};
struct node *head=NULL;
void printMenu();
void getUserSelection(int *);
void performOperation(int );
void display(void);
void addNodeAtBeginning(void);
struct node* createNode(void);
void displayLinkedList(void);
void addNodeAtEnd(void);
void getDataFromUser(char*);
void addAtuserSpecificLocation(void);
int getLocationFromUser(void);
void deleteFirstNode(void);
void deleteLastNode(void);
void deleteFromAspecificPosition(void);
void deleteEntireList(void);
int main(){
int option=0;
while(9!=option){
printMenu();
getUserSelection(&option);
performOperation(option);
}
getchar();
return 0;
}
void printMenu(){
printf("\n");
printf("\n***********MENU***************\n");
printf("1) Add a node at the beginning\n");
printf("2) Add a node at the end\n");
printf("3) Add a node at a user selected position\n");
printf("4) Delete first Node\n");
printf("5) Delete last Node\n");
printf("6) Delete node at a user selected position\n");
printf("7) Display\n");
printf("8) Delete entire list\n");
printf("9) Exit");
}
void getUserSelection(int *number){
printf("\nSelect an option: ");
scanf("%d",number);
}
void performOperation(int option){
switch(option){
case 1:
addNodeAtBeginning();
break;
case 2:
addNodeAtEnd();
break;
case 3:
addAtuserSpecificLocation();
break;
case 4:
deleteFirstNode();
break;
case 5:
deleteLastNode();
break;
case 6:
deleteFromAspecificPosition();
break;
case 7:
displayLinkedList();
break;
case 8:
deleteEntireList();
break;
case 9:
exit(0);
break;
default:
printf("\n\n********Invalid option**************\n\n");
break;
}
}
void addNodeAtBeginning(void){
struct node *tempNode=NULL;
if(NULL==head) {
head= createNode();
}else{
tempNode=createNode();
tempNode->next=head;
head=tempNode;
}
}
void addNodeAtEnd(){
struct node*tempNode=NULL;
if(NULL==head) {
head=createNode();
}else{
tempNode=head;
while(NULL!=tempNode->next){
tempNode=tempNode->next;
}
tempNode->next=createNode();
}
}
struct node* createNode(){
struct node *tempNode;
tempNode= (struct node*)malloc(sizeof(struct node));
getDataFromUser(&tempNode->data);
tempNode->next=NULL;
return tempNode;
}
void displayLinkedList(){
struct node *tempNode;
printf("\n\n********************LINKED_LIST_DOUBLY*******************************\n\n\n");
tempNode=head;
printf("[head]-->");
while(NULL!=tempNode->next){
printf("[%c]", tempNode-> data);
printf("--->");
tempNode=tempNode->next;
}
printf("[%c]", tempNode->data);
printf("-->[X]");
printf("\n\n********************LINKED_LIST_DOUBLY*******************************\n\n\n");
}
void getDataFromUser(char * data){
fflush(stdin);
printf("Enter data: ");
scanf("%c",data);
}
void addAtuserSpecificLocation(void){
int location;
struct node *tempNode=NULL;
struct node *tempUserNode=NULL;
tempNode=head;
location=getLocationFromUser();
int i;
for(i=1;i<location-1;i++){
tempNode=tempNode->next;
}
tempUserNode=createNode();
tempUserNode->next=tempNode->next;
tempNode->next=tempUserNode;
}
int getLocationFromUser(void){
int location;
int linkedListLength;
linkedListLength=getLengthOfLinkedList();
while(location<0||location>linkedListLength){
printf("\n\nEnter a valid location: ");
scanf("%d",&location);
}
return location;
}
int getLengthOfLinkedList(){
struct node *temp;
int length=1;
if(NULL==head){
printf("\n\nLinked list is empty cannot perform operation\n\n");
}else{
temp=head;
while(temp->next!=NULL){
length++;
temp=temp->next;
}
}
return length;
}
void deleteFirstNode(void){
struct node *tempNode=NULL;
if(NULL!=head){
tempNode=head;
head=head->next;
free(tempNode);
}else{
printf("\n\nThere is no node to delete\n\n");
}
}
void deleteLastNode(void){
struct node *tempNode;
if(NULL!=head){
tempNode=head;
while(NULL!=tempNode->next){
tempNode=tempNode->next;
}
free(tempNode);
}else{
printf("\n\nThere is no node to delete\n\n");
}
}
void deleteFromAspecificPosition(void){
int location;
struct node *tempNode;
if(NULL!=head){
tempNode=head;
location = getLocationFromUser();
int listIterator=0;
for(listIterator=0; listIterator<location-1;listIterator++){
tempNode=tempNode->next;
}
free(tempNode);
}
}
void deleteEntireList(void){
struct node* tempNode;
struct node* tempNode2;
if(NULL==head){
printf("\n\nList is already empty\n\n");
}else{
tempNode=head;
while(tempNode->next!=NULL){
tempNode2=tempNode->next;
free(tempNode);
tempNode=tempNode->next;
}
free(tempNode2);
head=NULL;
printf("\n\nList Deleted\n\n");
}
}
In delete_node(int val) the prev pointer is not initialised. The statement prev->next = tmp->next; gives undefined behaviour. Initialise the pointer:
list * prev = head;
Also the printf statement follows the free(tmp); statement. printf is printing variables in memory which have already been de-allocated. The free call should follow the printf statement.
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
free(tmp);
In delete_node, you declare variable prev, but you do not assign any value to it:
list* prev;
As the required value (5) is in the first list element, it will execute this statement:
prev->next = tmp->next;
with prev undefined, therefore unleashing SegmentFault.
That's what's causing the error.
The simplest solution is just to handle the case when wanted element is the first one by setting prev to NULL in declaration and checking if it is NULL in the while loop:
...
int delete_node(int val)
{
list* tmp = NULL;
list* prev = NULL;
tmp = head;
while(tmp){
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
if (prev) {
prev->next = tmp->next;
}
...
You should also consider doing it without global variables.

Resources