Program immediately terminates with segfault when using scanf - c

When I use gets() or fgets() instead of scanf(), the program does execute completely but prints segmentation fault(core dumped) in the end! I don't understand why am I getting segfault in both the cases. Here is the code for converting an infix to postfix exp using stacks.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct stack{
int top;
int capacity;
int *array;
}stack;
stack* createstack(char *);
void push(stack* ,int );
int isempty(stack *);
int pop(stack *st);
int peek(stack *st);
int precedence(char c);
int main(){
char exp[100];
char post[100];
int k=-1;
stack *st;
int i=0,p=0;
printf("enter string expression: ");
//gets(exp);
//fgets(exp, sizeof(exp), stdin);
scanf("%s",exp);
printf("Infix expression : %s",exp);
st=createstack(exp);
for(i=0;i<strlen(exp);i++){
if( (exp[i]>='a' && exp[i]<='z') || (exp[i]>='A' && exp[i]<='Z'))
post[++k]=exp[i];
else if(exp[i]=='(')
push(st,exp[i]);
else if(exp[i]==')'){
while(!isempty(st) && peek(st)!='(')
post[++k]=pop(st);
pop(st);
}
else{
while(precedence(exp[i]) < precedence(peek(st)))
post[++k]=pop(st);
push(st,exp[i]);
}
}
while(!isempty(st))
post[++k]=pop(st);
//post[++k]='\0';
printf("Postfix expression :\n%s\n",post);
return 0;
}
stack* createstack(char *exp){
stack* st;
st->top=-1;
st->capacity=strlen(exp);
st->array=(int*)malloc(st->capacity * sizeof(int));
printf("Stack created successfully\n");
return st;
}
void push(stack* st,int val){
st->array[++st->top]=val;
}
int isempty(stack *st){
return st->top==-1;
}
int pop(stack *st){
return st->array[st->top--];
}
int peek(stack *st){
return st->array[st->top];
}
int precedence(char c){
switch(c){
case '(':
return 0;
break;
case '+':
return 1;
break;
case '-':
return 1;
break;
case '*':
return 2;
break;
case '/':
return 2;
break;
case '^':
return 3;
break;
}
}

In your code,
stack* st;
st->top=-1;
you're using st uninitialized which in turn invokes undefined behaviour.
You need to allocate memory to st before using it.
Try something like
stack* st = malloc(sizeof*st); //also, check for malloc success
That said,
Please see why not to cast the return value of malloc() and family in C.
The recommended signature of main() is int main(void).

Related

Segmentation fault while implementing stack as an array

This is a menu-driven program that carries out basic stack operations using arrays in the C programming language. The functions that are performed are push, pop, peep,isempty and isfull.
#include<stdio.h>
#include<stdlib.h>
struct stack
{
long int top;
long int size;
char* key;
};
int is_empty(struct stack *s) //check if its empty
{
if(s->top==-1)
{
return -1;
}
else
{
return 1;
}
}
int is_full(struct stack *s) //check if its full
{
if (s->top ==s->size-1)
{
return -1;
}
else
{
return 1;
}
}
void push(struct stack *s, char x) //pushes into stack
{
int check;
check = is_full(s);
if(check==-1)
{
printf("-1\n");
}
else
{
s->top = s->top+1;
s->key[s->top]=x;
}
}
void pop(struct stack *s) //deletes the last element
{
int check;
check = is_empty(s);
if(check==-1)
{
printf("-1\n");
}
else
{
char k;
k = s->key[s->top];
printf("%c\n",k);
s->top--;
}
}
void peep(struct stack *s) //prints the last element without deleting
{ int check;
char k;
check = is_empty(s);
if (check == -1)
{
printf("-1\n");
}
else
{
k = s->key[s->top];
printf("%c \n",k);
}
}
int main()
{
char ch;
char x;
long int n;
struct stack *s;
scanf("%ld ", &n);
s->size = n; //initialise the size
s->top = -1; //setting as -1 base case
s->key= (char *)malloc(n*sizeof(char)); //dynamic allocation of keys
while(1)
{
scanf("%c ",&ch);
switch(ch)
{
case 'i':
scanf("%c ",&x);
push(s,x);
break;
case 'd':pop(s);
break;
case 'p':peep(s);
break;
case 't':exit(0); //termination case
}
}
return 0;
}
This is a C program that is working for me in some online compilers but in VScode and other compilers, it's showing a segmentation fault without any output. This is an implementation of stack using arrays. Is it a problem with any of the scanf functions?
You have created a pointer variable s and then access the size field on that struct.
struct stack *s;
scanf("%ld ", &n);
s->size = n; //initialise the size
Except s doesn't actually point to anything at this point. You need to either statically or dynamically allocate memory for that struct.
struct stack s;
Or:
struct stack *s = malloc(sizeof(struct stack));

Converting an infix to a prefix using stacks in C

I am trying to use stacks with linked lists to convert an infix expression to a prefix expression. Here is my code for the same:
#include <stdio.h>
#include <stdlib.h>
#define M 100
struct Stack{
char ele;
struct Stack *next;
};
struct Stack* next_node(char element){
struct Stack *node=(struct Stack *)malloc(sizeof(struct Stack));
node->ele=element;
node->next=NULL;
return node;
}
int isEmpty(struct Stack *node){
return node==NULL;
}
void push(struct Stack **node, char element){
struct Stack *temp=next_node(element);
temp->next=*node;
*node=temp;
}
char pop(struct Stack **node){
if(isEmpty(*node)){
return 0;
}
struct Stack *temp=*node;
*node=(*node)->next;
char revc=temp->ele;
free(temp);
return revc;
}
char* rev(char str[]){
int i, n;
for(n=0;str[n]!='\0';n++);
struct Stack *s=(struct Stack *)malloc(sizeof(struct Stack));
for(i=0;i<n;i++)
push(&s, str[i]);
for(i=0;i<n;i++)
str[i]=pop(&s);
if(str[i]=='(')
str[i]=')';
else if(str[i]==')')
str[i]='(';
return str;
}
int isVariable (char ch){
return (ch>='a' && ch<='z')||(ch>='A'&&ch<='Z');
}
int precedence(char ch){
switch(ch){
case '+':
case '-': return 1;
case '*':
case '/': return 2;
}
return -1;
}
char* postfix(char str[]){
int i, j=0;
struct Stack *s=NULL;
for(i=0;str[i]!='\0';i++){
if(isVariable(str[i]))
str[j++]=str[i];
else if(str[i]==')')
push(&s, str[i]);
else if(str[i]=='('){
while(!isEmpty(s)&&s->ele!=')')
str[j++]=pop(&s);
if(!isEmpty(s)&&s->ele!=')')
return 0;
else
pop(&s);
}
else{
while(!isEmpty(s)&&precedence(str[i])<=precedence(s->ele))
str[j++]=pop(&s);
push(&s, str[i]);
}
}
while(!isEmpty(s))
str[j++]=pop(&s);
str[j++]='\0';
return str;
}
void prefix(char str[]){
str=rev(str);
str=postfix(str);
str=rev(str);
printf("The prefix equivalent is: %s\n", str);
}
int main()
{
char string[M], op[1];
do{
printf("Enter the infix expression: ");
scanf("%s", string);
prefix(string);
printf("Do you want to go again?(Y/N): ");
scanf("%s", op);
}while(op[0]=='Y');
}
While the code works fine for expressions with no parantheses, it fails with expressions that do.
For example: when I input something like "(a+b-c) *d-(e+f)", my output is "- * a-b+cd+ef", when the output should be "- * -+abcd+ef".
Why is it happening? Any help is welcome! :-)

Getting user inputs in Postfix calculator in C by using stacks,

I am learning data structures and C and make a Postfix calculator as an exercise. the calculator works fine. but it is not able to get the equation from the user, For now, I defined a expression in the code itself.
What i want is, the user can enter expression one by one so it will give the value until he enters "Stop". How can i do that ??
This is my code
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
// Stack type
struct Stack
{
int top;
unsigned capacity;
int* array;
};
// Stack Operations
struct Stack* createStack( unsigned capacity )
{
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
if (!stack) return NULL;
stack->top = -1;
stack->capacity = capacity;
stack->array = (int*) malloc(stack->capacity * sizeof(int));
if (!stack->array) return NULL;
return stack;
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1 ;
}
int peek(struct Stack* stack)
{
return stack->array[stack->top];
}
int pop(struct Stack* stack)
{
if (!isEmpty(stack))
return stack->array[stack->top--] ;
return '$';
}
void push(struct Stack* stack,int op)
{
stack->array[++stack->top] = op;
}
int evaluatePostfix(char* exp)
{
struct Stack* stack = createStack(strlen(exp));
int i;
if (!stack) return -1;
for (i = 0; exp[i]; ++i)
{
if(exp[i]==' ')continue;
else if (isdigit(exp[i]))
{
int num=0;
while(isdigit(exp[i]))
{
num=num*10 + (int)(exp[i]-'0');
i++;
}
i--;
push(stack,num);
}
else
{
int val1 = pop(stack);
int val2 = pop(stack);
switch (exp[i])
{
case '+': push(stack, val2 + val1); break;
case '-': push(stack, val2 - val1); break;
case '*': push(stack, val2 * val1); break;
case '/': push(stack, val2/val1); break;
}
}
}
return pop(stack);
}
int main()
{
char exp[] = "100 200 + 2 / 5 * 7 +";
printf ("%d", evaluatePostfix(exp));
return 0;
}
I want to change this a a user input expression
char exp[] = "100 200 + 2 / 5 * 7 +";
How can i do it. any leads ???

Unable to pop top element from the linked list

I was trying to make a simple Linked List program, also when I'm trying to pop the first element from the list , it's not popping and it still remains the first element in the list, please help me resolve this error.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
void create(stack *s){
if(s == NULL){
s = (stack*)malloc(sizeof(stack)*1);
(s->next)=NULL;
}
else{
stack *temp = (stack*)malloc(sizeof(stack)*1);
(temp->next)=s;
s=temp;
}
}
void push(stack *s, char x){
create(s);
(s->value)=x;
}
void isEmpty(stack *s){
if(s == NULL){
printf("List is Empty!\n");
}
else{
printf("List is not Empty!\n");
}
}
char pop(stack *s){
if(s == NULL){
isEmpty(s);
return -1;
}
char x=s->value;
s=(s->next);
return x;
}
int main(int argc , char* argv[]){
stack *s;
create(s);
char choice,data;
printf("Stack Created\n\n");
do{
printf("Choose Option: pUsh, pOp, pEek, iseMpty, getSize, eXit: \n");
scanf(" %c",&choice);
switch(choice){
case 'U':{
printf("Enter the element to be pushed: \n");
scanf(" %c",&data);
push(s, data);
break;
}
case 'O':{
data=pop(s);
if(data != NULL){
printf("Popped: %c\n", data);
}
break;
}
}
}while(1);
return 0;
}
The line s=s->next; has no effect because s is a local varaible. You need to return the new value of s or use pointers to modify the caller's version.
I changed the argument to pop() and push() from stack * to stack **, so that we can update the stack not a local variable. I removed create() as it is basically what happens during the push and I integrated it with that.
The rest is straightforward and I also added the free() call in pop(). Take a look:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack{
int value;
struct stack *next;
}stack;
void push(stack **s, int x){
stack *temp = (stack*)malloc(sizeof(stack)*1);
temp->value = x;
temp->next = NULL;
if(*s == NULL){
*s = temp;
}else{
temp->next = *s;
*s=temp;
}
}
char pop(stack **s){
if(*s == NULL){
return -1;
}
char x=(*s)->value;
stack *tmp = *s;
*s=(*s)->next;
free(tmp);
return x;
}
int main(int argc , char* argv[]){
stack *s;
char choice,data;
printf("Stack Created\n\n");
do{
printf("Choose Option: pUsh, pOp, pEek, iseMpty, getSize, eXit: \n");
scanf(" %c",&choice);
switch(choice){
case 'U':{
printf("Enter the element to be pushed: \n");
scanf(" %c",&data);
push(&s, data);
break;
}
case 'O':{
data=pop(&s);
if(data != -1){
printf("Popped: %c\n", data);
} else {
printf("Stack is empty. nothing popped");
}
break;
}
}
}while(1);
return 0;
}
Here you have to use pointer to pointer if u want to pass pointer as an argument
char pop(stack **s)
{
**s=s->next;
}
this is a temporary solution u should also consider deleting the memory you allocated using the malloc function or else it will lead to memory leak
also pass the address of the pointer s while you call it in the pop function

ERROR when using malloc() and sizeof() function

Following is a program I made in C for implementation of stack using array and pointers:
#include<stdio.h>
#include<stdlib.h>
struct ArrayStack {
int top;
int capacity;
int *array;
};
struct ArrayStack *createStack(int cap) {
struct ArrayStack *stack;
stack = malloc(sizeof(struct Arraystack));
stack->capacity = cap;
stack->top = -1;
stack->array(malloc(sizeof(int) * stack->capacity));
return stack;
}
int isFull(struct ArrayStack *stack) {
if(stack->top == stack->capacity-1)
return 1;
else
return 0;
}
int isEmpty(struct ArrayStack *stack) {
if(stack->top == -1)
return 1;
else
return 0;
}
void push(struct ArrayStack *stack, int item) {
if(!isFull(stack)) {
stack->top++;
stack->array[stack->top] = item;
} else {
printf("No more memory available!");
}
}
void pop(struct ArrayStack *stack) {
int item;
if(!isEmpty(stack)) {
item = stack->array[stack->top];
stack->top--;
} else {
printf("Memory is already empty!");
}
}
int main() {
struct ArrayStack *stack;
stack = createStack(10);
int choise;
int item;
while(1) {
system("clear");
printf("\n1. Push");
printf("\n2. Pop");
printf("\n3. Exit");
printf("\n\n\n\t\tPlease choose your option!");
scanf("%d",&choise);
switch(choise) {
case 1:
printf("\nEnter a number");
scanf("%d",&item);
push(stack,item);
break;
case 2:
pop(stack);
break;
case 3:
exit(0);
break;
default :
printf("\nPlease enter a valid choise!");
break;
}
}
}
The following error is coming whenever I try to compile this code using gcc compiler:
prog.c:10:25: error: invalid application of 'sizeof' to incomplete type 'struct Arraystack'
stack = malloc(sizeof(struct Arraystack));
^
prog.c:13:3: error: called object is not a function or function pointer
stack->array(malloc(sizeof(int) * stack->capacity));
^
I have used online IDEs like ideone and codechef's ide but same error is coming again. I am totally struck, this is really annoying!
First your errors:
stack = malloc(sizeof(struct ArrayStack));
You typed Arraystack (lower case s).
stack->array=malloc(sizeof(int) * stack->capacity);
You typed stack->array(malloc(sizeof(int) * stack->capacity)); which is syntactically a function call which is why the compiler complains about array not being a function pointer.
In addition:
Introduce a function void destroyStack(ArrayStack* stack) to free() the malloc()ed space in createStack(). Call it towards the end of main() when you've finished with the stack.
Always render unto free() what malloc() rendered unto thee.
Your pop() doesn't return the popped value.
You should probably return values indicating failure when push() and pop() fail.

Resources