Segmentation fault: Implementing Priority Queues in C - c

I'm trying to implement priority. A higher value of variable prior implies a lower priority in my code. Here it is:
#include <stdio.h>
#include <stdlib.h>
struct MinMax_PriorityQueue{
int ele, prior;
struct MinMax_PriorityQueue *next;
};
int isEmpty(struct MinMax_PriorityQueue **pq){
return ((*pq)==NULL);
}
int checkPriority(int p){
return(p>0);
}
void enqueue(struct MinMax_PriorityQueue **pq, int x, int p){
struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
//struct MinMax_PriorityQueue *temp1=*pq;
if(!checkPriority(p)){
printf("Priority should be greater than 0");
return;
}
temp->ele=x;
temp->prior=p;
temp->next=NULL;
/*if(isEmpty(pq)){
*pq=temp;
}
while(temp1->next!=NULL){
temp1=temp1->next;
}*/
(*pq)->next=temp;
printf("The item %d with priority %d has been enqueued into the priority queue\n", x, p);
}
int maxPriority(struct MinMax_PriorityQueue **pq){
struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
temp=*pq;
int maxp=temp->prior;
while(temp!=NULL){
if(temp->prior<=maxp)
maxp=temp->prior;
temp=temp->next;
}
return maxp;
}
void dequeue(struct MinMax_PriorityQueue **pq){
if(isEmpty(pq)){
printf("The priority queue is empty. No more elements can be removed!\n");
}
int maxp=maxPriority(pq);
struct MinMax_PriorityQueue *temp=*pq;
while(temp!=NULL){
if(temp->prior==maxp){
printf("The item %d with priority %d has been dequeued from the priority queue\n", temp->ele, temp->prior);
free(temp);
break;
}
temp=temp->next;
}
}
void minSearch(struct MinMax_PriorityQueue **pq){
struct MinMax_PriorityQueue *temp=malloc(sizeof(*temp));
temp=*pq;
int minp=0;
while(temp!=NULL){
if(temp->prior>=minp)
minp=temp->prior;
temp=temp->next;
}
temp=*pq;
while(temp!=NULL){
if(temp->prior==minp){
printf("The element %d has minimum priority\n", temp->ele);
}
temp=temp->next;
}
}
void maxSearch(struct MinMax_PriorityQueue **pq){
int maxp=maxPriority(pq);
struct MinMax_PriorityQueue *temp=*pq;
while(temp!=NULL){
if(temp->prior==maxp){
printf("The element %d has maximum priority\n", temp->ele);
}
temp=temp->next;
}
}
void display(struct MinMax_PriorityQueue *pq){
struct MinMax_PriorityQueue *temp=pq;
printf("The contents of the priority queue are:\n");
if(isEmpty(&temp)){
printf("Nothing to be shown, the priority queue is empty.\n");
return;
}
for(int i=0;temp!=NULL;temp=temp->next){
if(i){
printf(" ------ \n");
}
printf("| %d |\n", temp->ele);
i=1;
}
}
int main()
{
int choice, element, priority;
printf("LET'S START WITH AN EMPTY QUEUE\n\n");
struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq));
pq=NULL;
while(1){
printf("\nMENU\n");
printf("----\n");
printf("\t1. Enqueue\n");
printf("\t2. Dequeue\n");
printf("\t3. Display queue\n");
printf("\t4. Search minimum priority\n");
printf("\t5. Search maximum priority\n");
printf("\t6. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice){
case 1: printf("Enter the element to be enqueued: ");
scanf("%d", &element);
printf("Enter its priority: ");
scanf("%d", &priority);
enqueue(&pq, element, priority);
break;
case 2: dequeue(&pq);
break;
case 3: display(pq);
break;
case 4: minSearch(&pq);
break;
case 5: maxSearch(&pq);
break;
case 6: printf("Program terminated successfully!\n");
return 0;
default: printf("Invalid input");
}
}
}
Upon enqueuing, I find a segmentation fault in the line: (*pq)->next
in the enqueue() function. I can't wrap my head around why that is happening. Is it because I took an argument of type struct MinMax_PriorityQueue **?
Any help is appreciated.

(*pq)->next=temp; in the enqueue function causes segfault as *pq is NULL on the first call.
You shouldn't have commented out the check for NULL. You need it.. but like
if(isEmpty(pq)){
*pq=temp;
return; // Add this
}
BTW:
The reason the *pq is NULL on the first call of enqueue is this code in main
struct MinMax_PriorityQueue *pq=malloc(sizeof(*pq));
pq=NULL; // You set pq back to NULL (and leaks memory)
But you shouldn't do the malloc in main to start with. Simply do:
struct MinMax_PriorityQueue *pq=NULL; // Empty queue

Related

Linear queue implementation using C. Compiler doesn't show any error but program not running(shows error message: program has stopped working)

I am trying to implement linear queue using C but the program doesn't run even though the compiler doesn't show any error. When i try to run the program a pop up windows says "The program has stopped working". Can anyone show me what is wrong with this code and how to fix it? Any help will be appreciated.
Thank you
```
#include<stdio.h>
#define MAXSIZE 30
struct queue{
int item[MAXSIZE];
int rear;
int front;
};
typedef struct queue qu;
void enqueue(qu *q){
int data;
printf("Enter the data to be inserted(enqueued) \n");
scanf("%d", &data);
if(q->rear == MAXSIZE-1){
printf("Queue is full \n");
}
else{
q->rear++;
q->item[q->rear] = data;
}
}
void dequeue(qu *q){
if(q->rear < q->front){
printf("queue is empty \n");
}
else{
q->front++;
printf("Deleted item is \n %d \n", q->item[q->front]);
}
}
void display(qu *q){
int i;
if(q->rear < q->front){
printf("queue is empty \n");
}
else{
printf("The queue is : \n");
for( i=q->front; i<= q->rear; i++){
printf("%d \t",q->item[i]);
}
}
}
int main(){
int ch;
qu *q;
q->front = 0;
q->rear = -1;
printf("MENU for operation \n");
printf("1: Enqueue \n 2: Dequeue \n 3: Display \n 4: Exit \n");
do{
printf("Choose an operation \n");
scanf("%d", &ch);
switch(ch){
case 1:
enqueue(q);
break;
case 2:
dequeue(q);
break;
case 3:
display(q);
break;
case 4:
break;
default:
printf("Choose number from 1-4");
}
}
while(ch != 4);
return 0;
}
With qu *q; you define a pointer with indeterminate value to a qu object; this is of no use. Instead you've to define qu q; and write q. everywhere you wrote q-> and (&q) everywhere you wrote (q), respectively, in main.
Then in dequeue with
q->front++;
printf("Deleted item is \n %d \n", q->item[q->front]);
you erroneously increment front before taking the front item from the queue; correct:
printf("Deleted item is \n %d \n", q->item[q->front++]);
Finally note that your queue implementation could be improved by reusing released queue positions.

Segmentation fault - Implementing Stack using Queues

I'm implementing a stack using two queues. I'm quite familiar with the algorithm, and have prepared the following code where the push operation is costly:
#include <stdio.h>
#include <stdlib.h>
struct queue_struct{
int ele;
struct queue_struct *next;
};
struct Queue{
struct queue_struct *front, *rear;
};
struct Stack{
struct Queue *q1, *q2;
};
void enqueue(struct Queue *q, int x){
struct queue_struct *temp=malloc(sizeof(*temp));
temp->ele=x;
temp->next=NULL;
if(q->rear!=NULL){
q->rear->next=temp;
}
q->rear=temp;
if(q->front==NULL)
q->front=temp;
//printf("The item %d has been enqueued into the queue\n", x);
}
void dequeue(struct Queue *q){
struct queue_struct *temp=q->front;
if(temp==NULL){
//printf("The queue is already empty. No more elements can be removed!\n");
return;
}
printf("The item %d has been popped from the stack\n", temp->ele);
q->front=temp->next;
if(q->rear==temp)
q->rear=NULL;
free(temp);
}
void push(struct Stack *s, int x){
enqueue(s->q2, x);
while(!(s->q1->front==NULL)){
enqueue(s->q2, s->q1->front->ele);
dequeue(s->q1);
}
struct Queue *q=s->q1;
s->q1=s->q2;
s->q2=q;
printf("The item %d has been pushed into the stack\n", x);
}
void pop(struct Stack *s){
if(s->q1->front==NULL){
printf("The stack is already empty. No more elements can be removed!\n");
return;
}
dequeue(s->q1);
}
void display(struct Stack *s){
struct queue_struct *temp=s->q1->front;
printf("The contents of the queue are:\n");
if(temp==NULL){
printf("Nothing to be shown, the queue is empty.\n");
return;
}
for(int i=0;temp!=NULL;temp=temp->next){
if(i){
printf(" ------ \n");
}
printf("| %d |\n", temp->ele);
i=1;
}
}
int main()
{
int choice, element;
struct Stack *s=malloc(sizeof(*s));
s->q1->front=s->q1->rear=NULL;
s->q2->front=s->q2->rear=NULL;
printf("LET'S START WITH AN EMPTY STACK\n\n");
while(1){
printf("MENU\n");
printf("----\n");
printf("\t1. Push an element\n");
printf("\t2. Pop an element\n");
printf("\t3. Display stack\n");
printf("\t4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice){
case 1: printf("Enter the element to be pushed: ");
scanf("%d", &element);
push(s, element);
break;
case 2: pop(s);
break;
case 3: display(s);
break;
case 4: printf("Program terminated successfully!");
return 0;
default: printf("Invalid input");
}
}
}
However, I'm getting a Segmentation fault for the line(s): s->q1->front=s->q1->rear=NULL;. I'm not really sure why it is happening and how to fix it. Any help is appreciated.
You invoked undefined behavior by using values in buffer allocated via malloc() and not initialized.
You have to initialize s->q1 and s->q2 before dereferencing them.
struct Stack *s=malloc(sizeof(*s));
if (s == NULL) return 1; /* check if allocation succeeded */
s->q1 = malloc(sizeof(*s->q1)); /* allocate for s->q1 */
s->q2 = malloc(sizeof(*s->q2)); /* allocate for s->q2 */
if (s->q1 == NULL || s->q2 == NULL) return 1; /* check if allocations succeeded */
s->q1->front=s->q1->rear=NULL;
s->q2->front=s->q2->rear=NULL;

Double Linked List query

so i have created a program which uses double linked list and
performs some operations on it . The problem is that it displays garbage
values
at the end every time i try to create a linked list and then display it.
whats wrong in my code?(sorry! for the bad indentations)
if the linked list i created has elements say 15 and 16, it displays it as
15 16 25710 0 0
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct dll
{
int data;
struct dll *llink;
struct dll *rlink;
};
typedef struct dll *node;
node head=NULL;
void create();
int search(int u);
void insert(int num1);
void Delete(int num2);
void display();
node getnode();
int main()
{
int i,num,o;
while(1)
{
printf("\n1.create a list\n 2. insert before a search node\n 3. delete a node\n 4.display\n 5.exit\n");
scanf("%d",&num);
switch(num)
{
case 1 :
create();
break;
case 2 :
printf("enter the value before which you want to enter the node\n");
scanf("%d",&i);
insert(i);
break;
case 3 :
printf("enter the value to be deleted\n");
scanf("%d",&o);
Delete(o);
break;
case 4 :
printf("the linked list has :\n");
display();
break;
case 5 :
getch();
exit(1);
default :
printf("enter the correct option\n");
break;
}
}
}
node getnode()
{
node temp1;
temp1=(node)malloc(sizeof(node));
temp1->llink=NULL;
temp1->rlink=NULL;
return temp1;
}
void create()
{
node nn;
int num,y;
if(head==NULL)
head=getnode();
while(1)
{
printf("enter the data for the node");
scanf("%d",&num);
head->data=num;
printf("do you want to create another node(1/0):\n");
scanf("%d",&y);
if(y==1)
{
nn=getnode();
nn->rlink=head;
head->llink=nn;
head=nn;
nn=NULL;
}
else
break;
}
}
void insert (int num1)
{
int i,n,k;
node temp=head,nn;
n=search(num1);
if(n==0)
{
printf("element not present in the linked list");
}
if(n==1)
{
nn=getnode();
printf("enter the data for the node");
scanf("%d",&k);
nn->data=k;
nn->rlink=head;
head->llink=nn;
head=nn;
nn=NULL;
}
else
{
for(i=2; i<=n; i++)
temp=temp->rlink;
nn=getnode();
temp->llink->rlink=nn;
nn->llink=temp->llink;
nn->rlink=temp;
temp->llink=nn;
}
}
void Delete(int num2)
{
node temp=head;
int p,i;
p=search(num2);
if(p==0)
{
printf("no element is found");
}
if(p==1)
{
printf("the deleted element is %d",head->data);
head=head->rlink;
head->llink=NULL;
free(temp);
}
else
{
for(i=2; i<=p; i++)
{
temp=temp->rlink;
}
temp->llink->rlink=temp->rlink;
temp->rlink->llink=temp->llink;
free(temp);
temp=temp->rlink;
}
}
int search(int u)
{
node temp=head;
int pos=0;
if(u==head->data)
return 1;
else
{
while(temp!=NULL)
{
pos++;
if(temp->data==u)
{
printf("element found\n");
return(pos);
}
temp=temp->rlink;
}
}
if(temp==NULL)
{
return 0;
}
return -1;
}
void display()
{
node temp=head;
while(temp!=NULL)
{
printf("%d\n",temp->data);
temp=temp->rlink;
}
}
This:
temp1=(node)malloc(sizeof(node));
is a major error. Since you're "hiding a star", and node is a typedef for a pointer type, you're not allocating enough memory. It should be:
node temp1 = malloc(sizeof *temp1);
But I really recommend against typedefing a pointer away, it just makes things confusing.

Why does my code skip over certain nodes?

I'm writing this code to store data records of students' first name, last name, scores and zip codes. I have almost everything done but my Print() function doesn't print the first element of node 2(first name of 2nd student) and turns into an infinite loop when I input ore than 2 nodes, what am i doing wrong?
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
void Insert(char first[20], char last[20], float data, char zip[50]);
void delete(int e);
void Print();
double median();
struct node
{
char first_name[20];
char last_name[20];
float score;
char zip_code[50];
struct node *ptr;
};
int n;
struct node* head =NULL;
struct node* tail=NULL ;
void Insert(char first[20], char last[20], float data, char zip[50])
{
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp->ptr=NULL;
strcpy(temp->first_name,first);
strcpy(temp->last_name,last);
temp->score=data;
strcpy(temp->zip_code,zip);
if(head==NULL)
{
head=temp;
tail=temp;
return;
}
tail->ptr=temp;
tail=temp;
free(temp);
temp=NULL;
}
void delete(int e)
{
int i;
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
if(e==1)
{
head=temp->ptr;
free(temp);
return;
}
else if(e==n)
{
while(temp->ptr->ptr!=NULL)
{
temp=temp->ptr;
}
temp->ptr=NULL;
free(temp->ptr);
return;
}
for(i=0; i<(e-2); ++i)
temp=temp->ptr;
struct node *temp1=temp->ptr;
temp->ptr=temp1->ptr;
free(temp1);
}
void Print()
{
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
printf("Data entered is below: \n");
while(temp!=NULL)
{
printf("First Name: %s, Last Name: %s, Score: %.2f, Zip Code: %s",temp->first_name,temp->last_name,temp->score,temp->zip_code);
temp=temp->ptr;
printf("\n");
}
printf("\n\n\n");
}
double median()
{
double median,tmp;;
double *ex=(double*)malloc(sizeof(double));/*head*/
double *exe=(double*)malloc(sizeof(double));/*dynamic*/
ex=exe;
int i=1,term,j;
struct node *temp=(struct node*)malloc(sizeof(struct node));
temp=head;
while(i<=n)
{
temp->ptr;
*exe=temp->score;
exe++;
}
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
if( *(ex+i) > *(ex+j))
{
tmp = *(ex+i);
*(ex+i) = *(ex+j);
*(ex+j) = tmp;
}
}
}
if(n%2==0)
{
/*even;median=n/2-1*/
term=(n/2)-1;
median= (*(ex+(term-1)));
return median;
}
/*odd; median=n-1/2*/
term=(n-1)/2;
median= (*(ex+(term-1)));
return median;
}
int main()
{
char name1[20],name2[20], code[50];
float x;
int i,option,index;
printf("Enter the number of nodes: ");
scanf("%d",&n);
printf("Please enter the records of students in the following format(click enter for new students)\n");
printf("First_Name Last_Name Score Zip_Code\n");
for(i=1; i<=n; ++i)
{
scanf(" %s",name1);
scanf(" %s",name2);
scanf(" %f",&x);
scanf(" %s",code);
Insert(name1,name2,x,code);
}
printf("\n");
while(1)
{
printf("Choose one of the following options: \n");
printf("Print records (press 1)\nAdd a new record (press 2)\nDelete record(s) (press 3)\nSearch by zip code (press 4)\nSearch by score range (press 5)\nFind median score (press 6)\nExit the program (press 0)\n");
scanf("%d",&option);
switch(option)
{
case 0:
{
/*Exit Program*/
exit(0);
break;
}
case 1:
{
/*print*/
Print();
break;
}
case 2:
{
/*insert*/
getchar();
printf("Enter the new record in the following format: \nFirst_Name Last_Name Score Zip_Code\n");
scanf("%s",name1);
scanf("%s",name2);
scanf("%f",&x);
scanf("%s",code);
getchar();
Insert(name1,name2,x,code);
break;
}
case 3:
{
/*delete*/
printf("Enter the node/record to be deleted: ");
scanf("%d",&index);
delete(index);
printf("The deletion of record %d has been succesfully completed!\n\n",index);
break;
}
case 4:
{
/*search by zip*/
break;
}
case 5:
{
/*search by score*/
break;
}
case 6:
{
/*find median*/
printf("Median score for the entered records is: %f",median());
break;
}
}/*switch*/
}/*while*/
return 0;
}
The Insert function is holding a reference to freed data:
tail=temp;
free(temp);
Attempting to use the storage referenced by tail after it's been freed is an error.

Inorder successor of Threaded Binary Tree

I am writing a c program to create threaded binary tree and then to find INORDER SUCCESSOR of a particular node. For this, i am displaying inorder sequence for the TBT constructed and then asking user to input the node to which successor is to be displayed.. I have written function to do this. But i am not getting successor for the FIRST NODE .. Last node's successor is 0 any ways its working fine.. Can any one help me fix this ?
Here is the whole program :
#include<stdio.h>
#include <stdlib.h>
struct tbtnode {
int data;
struct tbtnode *left,*right;
int lbit,rbit,flag;
int child;
}*root=NULL;
typedef struct tbtnode TBT;
TBT *insuc(TBT *t);
void inorder(TBT *);
void create(TBT *);
void create(TBT *root)
{
int x,op,flag,y;
flag=0;
char ch;
TBT *curr=root;
TBT *q,*p;
do
{
printf("\nCurrent node %d \n\n 1.Left Direction.\n\n2.Right Direction",curr->data);
printf("\nEnter ur choice :");
scanf("%d",&op);
switch(op)
{
case 1: if(curr->lbit==1)
{
printf("Enter left child of %d : ",curr->data);
scanf("%d",&x);
q=(TBT *)malloc(sizeof(TBT));
q->data=x;
q->lbit=q->rbit=1;
q->left=curr->left;
q->right=curr;
curr->left=q;
curr->lbit=0;
q->child=0;
flag=1;
}
else
curr=curr->left;
break;
case 2: if(curr->rbit==1)
{
printf("Enter right child of %d :",curr->data);
scanf("%d",&x);
q=(TBT *)malloc(sizeof(TBT));
q->data=x;
q->lbit=q->rbit=1;
q->left=curr;
q->right=curr->right;
curr->right=q;
curr->rbit=0;
q->child=1;
flag=1;
}
else
curr=curr->right;
break;
}
}while(flag==0);
}
void inorder(TBT *head)
{
TBT *t;
t=head->left;
printf("\n");
while(t->lbit==0)
t=t->left;
while(t!=head)
{
printf(" %d",t->data);
t=insuc(t);
}
}
TBT *insuc(TBT *t)
{
if(t->rbit==0)
{
t=t->right;
while(t->lbit==0)
t=t->left;
return(t);
}
else
return(t->right);
}
void inorder_successor(TBT *head,int x)
{
TBT *t;
t=head->left;
printf("\n");
while(t->lbit==0)
t=t->left;
while(t!=head)
{
t=insuc(t);
if(t->data==x)
{
t=insuc(t);
printf(" %d",t->data);
}
}
}
int main()
{
int op,x,n,i=0,item;
char ch;
TBT *head,*root,*succ; //here head indicates dummy variable
head=(TBT *)malloc(sizeof(TBT));
head->left=head;
head->right=head;
head->lbit=1;
head->rbit=1;
do
{
printf("\n****Threaded binary tree operations****");
printf("\n1)create\n2)inorder\n3)Successor\n4)exit");
printf("\nEnter ur choice: ");
scanf("%d",&op);
switch(op)
{
case 1:
printf("\nEnter Number Of Nodes :");
scanf("%d",&n);
printf("\nEnter root data: ");
scanf("%d",&x);
root=(TBT *)malloc(sizeof(TBT));
root->data=x;
root->lbit=root->rbit=1;
root->child=0;
root->left=head->left;
head->left=root;
head->lbit=0;
root->right=head->right;
for(i=0;i<n-1;i++)
create(root);
break;
case 2:
printf("\nInorder Traversal Is:\n");
inorder(head);
break;
case 3: printf("Enter the node to which successor is to be found\n");
scanf("%d",&item);
inorder_successor(head,item);
break;
case 4:
return(0);
break;
}
}while(op<=4);
return 0;
}
please fix - inorder_successor() function for me..
Thank you
You have many problems with your code. To start with you never check for NULL pointers. To continue, you have both a global and a local variable in main called root.
The last thing means that when you allocate memory for root in main, you allocate for the local variable, and the global variable will still be NULL.
There are also other things that look weird, like you assigning the left and right pointer of head to itself.
I think you need to lay it all out on paper first, both how you have it now and how you want it to be. It will help you to better visualize the tree.

Resources