I have implemented a Stack using dynamic array(implementing array doubling) but when the doubling happens for the second time, I am getting runtime error! What's going wrong with the implementation? Please help.
#include <stdio.h>
#include <stdlib.h>
struct Stack {
int *arr;
int top,size,capacity;
};
struct Stack *createStack(int capacity) {
struct Stack *s = (struct Stack*)malloc(sizeof(struct Stack));
s->arr = (int*)malloc(sizeof(int)*capacity);
s->top = -1;
s->capacity = capacity;
s->size = 0;
return s;
}
void doubleStack(struct Stack *s) {
s->capacity = s->capacity*2;
s->arr = realloc(s->arr,s->capacity);
printf("Array doubling happened successfully!\n");
}
int isFull(struct Stack *s) {
return s->size == s->capacity;
}
void push(struct Stack *s, int item) {
if(isFull(s))
doubleStack(s);
printf("%d pushed!\n",item);
s->arr[++(s->top)] = item;
s->size++;
}
int isEmpty(struct Stack *s) {
return s->size == 0;
}
void pop(struct Stack *s) {
if(isEmpty(s)) {
printf("Empty stack!\n");
return;
}
int item = s->arr[(s->top)--];
s->size--;
printf("%d popped!\n",item);
}
int main(void) {
struct Stack *s = createStack(2);
push(s,1);
push(s,2);
push(s,3);
push(s,4);
push(s,5);
pop(s);
pop(s);
return 0;
}
You failed to multiply the size to allocate via realloc() by sizeof(int).
Try this with some other improvement:
#include <stdio.h>
#include <stdlib.h>
struct Stack {
int *arr;
int top,size,capacity;
};
struct Stack *createStack(int capacity) {
struct Stack *s = malloc(sizeof(struct Stack));
s->arr = malloc(sizeof(int)*capacity);
s->top = -1;
s->capacity = capacity;
s->size = 0;
return s;
}
void destroyStack(struct Stack *s) {
if(s != NULL) free(s->arr);
free(s);
}
void doubleStack(struct Stack *s) {
s->capacity = s->capacity*2;
s->arr = realloc(s->arr,sizeof(int)*s->capacity);
if(s->arr != NULL) {
printf("Array doubling happened successfully!\n");
} else {
perror("realloc");
}
}
int isFull(struct Stack *s) {
return s->size == s->capacity;
}
void push(struct Stack *s, int item) {
if(isFull(s))
doubleStack(s);
printf("%d pushed!\n",item);
s->arr[++(s->top)] = item;
s->size++;
}
int isEmpty(struct Stack *s) {
return s->size == 0;
}
void pop(struct Stack *s) {
if(isEmpty(s)) {
printf("Empty stack!\n");
return;
}
int item = s->arr[(s->top)--];
s->size--;
printf("%d popped!\n",item);
}
int main(void) {
struct Stack *s = createStack(2);
push(s,1);
push(s,2);
push(s,3);
push(s,4);
push(s,5);
pop(s);
pop(s);
destroyStack(s);
return 0;
}
Related
When I try to implement parenthesis problem using stack (array representation) it showing above problem. Here I use dynamic memory allocation in array. When I try to compile the above program it appear built log like : process terminated with status -1073741510 (0 minute(s), 2 second(s))
#include<stdlib.h>
struct stack
{
int size;
int top;
char *arr;
};
int parenthematch(char *pt)
{
struct stack *st;
st->size = 100;
st->top = -1;
st->arr = (char *)malloc(st->size * sizeof(char)); //create array of st->size
for(int i=0; pt[i]!='\0'; i++)
{
if(pt[i]=='(')
{
push(st,'(');
}
else if(pt[i]==')')
{
if(isEmpty(st))
{
return 0;
}
pop(st);
}
}
int main()
{
char *p ="(34)(4(5+6))";
if(parenthematch(p))
{
printf("parenthesis match \n");
}
else
{
printf("Not match");
}
return 0;
} ```
#include <stdio.h>
#include <stdlib.h>
struct stack
{
size_t size;
int top;
char *arr;
};
void push(struct stack *st, char ch)
{
st->top += 1;
st->arr[st->top] = ch;
}
int isEmpty(struct stack *st)
{
return st->top == -1;
}
void pop(struct stack *st)
{
st->top -= 1;
}
int parenthematch(char *pt)
{
struct stack *st = (struct stack *)malloc(sizeof(struct stack));
st->size = 100;
st->top = -1;
st->arr = (char *)malloc(st->size * sizeof(char)); //create array of st->size
for (int i = 0; pt[i] != '\0'; i++)
{
if (pt[i] == '(')
{
push(st, '(');
}
else if (pt[i] == ')')
{
if (isEmpty(st) || st->arr[st->top] != '(')
{
return 0;
}
pop(st);
}
}
return isEmpty(st);
}
int main()
{
char p[] = "(34)(4(5+6))";
if (parenthematch(p))
{
printf("parenthesis match \n");
}
else
{
printf("Not match");
}
return 0;
}
Question is to to check in the character array if the parenthesis is matched or not using stack.
In my code i am not getting any output nor any error so i am unable to find my mistake.
At first i have made a structure for stack.
Then i have made functions to check whether the stack is empty or full to prevent conditions such as stack overflow or underflow.
Then i have made function for parenthesis checker
HERE IS MY CODE:
#include <stdio.h>
#include <stdlib.h>
//Initializing the stack with structures
struct stack
{
int size;
int top;
char *arr;
};
//function to check whether stack is empty
int isEmpty(struct stack *ptr)
{
if (ptr->top == -1)
{
return 1;
}
else
{
return 0;
}
}
//function to check whether stack is full
int isFull(struct stack *ptr)
{
if (ptr->top == (ptr->size - 1))
{
return 1;
}
else
{
return 0;
}
}
//Function for push
void push(struct stack *ptr, char val)
{
if (isFull(ptr))
{
printf("Stack Overflow, Cannot push more elements\n");
}
else
{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
//Function for pop
char pop(struct stack *ptr)
{
if (isEmpty(ptr))
{
printf("Stack Underflow, Unable to pop elements\n");
return -1;
}
else
{
char val;
val = ptr->arr[ptr->top];
ptr->top--;
return val;
}
}
//Function for parenthesis matching
int parenthesisChecker(char *exp)
{
struct stack *st;
st->size = 100;
//stack is empty for now
st->top = -1;
st->arr = (char *)malloc(st->size * sizeof(char));
int n_push = 0, n_pop = 0;
for (int i = 0; exp[i] != '\0'; i++)
{
//for open bracket push
if (exp[i] == '(')
{
push(st, '(');
n_push++;
}
//for closed bracket pop
else if (exp[i] == ')')
{
if (isEmpty(st))
{
return 0;
}
else
{
pop(st);
n_pop++;
}
}
}
printf("%d times push\n", n_push);
printf("%d times pop\n", n_pop);
if (isEmpty(st))
{
return 1;
}
else
{
return 0;
}
}
int main()
{
char *c = "akajvd)(()";
if (parenthesisChecker(c))
{
printf("Parenthesis is matched");
}
else
{
printf("Parenthesis is not matched");
}
return 0;
}
The pointer st within the function parenthesisChecker is not initialized and has an indeterminate value
struct stack *st;
So dereferencing the pointer like for example in this statement
st->size = 100;
invokes undefined behavior.
Also the function produces a memory leak because it does not free the memory allocated for the data member arr of the structure struct stack.
The function parameter should have the qualifier const because the passed string is not being changed within the function.
int parenthesisChecker( const char *exp );
And such functions as pop and push should not output any message. It is the caller of the functions that decides whether to output a message.
I would write the program the following way.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stack
{
size_t size;
size_t top;
char *arr;
};
struct stack make_stack( size_t size )
{
struct stack st = { .size = size, .top = 0, .arr = malloc( size ) };
if ( st.arr == NULL ) st.size = 0;
return st;
}
void free_stack( struct stack *st )
{
free( st->arr );
st->size = 0;
st->top = 0;
}
int isEmpty( const struct stack *st )
{
return st->top == 0;
}
int isFull( const struct stack *st )
{
return st->top == st->size;
}
int push( struct stack *st, char val )
{
int success = !isFull( st );
if ( success )
{
st->arr[st->top++] = val;
}
return success;
}
int pop( struct stack *st, char *val )
{
int success = !isEmpty( st );
if ( success )
{
*val = st->arr[--st->top];
}
return success;
}
int parenthesisChecker( const char *s )
{
int success = 1;
if ( *s != '\0' )
{
struct stack st = make_stack( strlen( s ) );
success = st.size != 0;
for ( ; success && *s; ++s )
{
if ( *s == '(' )
{
success = push( &st, *s );
}
else if ( *s == ')' )
{
char c;
success = pop( &st, &c );
}
}
success = success && isEmpty( &st );
free_stack( &st );
}
return success;
}
int main(void)
{
const char *s = "akajvd)(()";
if ( parenthesisChecker( s ) )
{
puts( "Parentheses are matched" );
}
else
{
puts( "Parentheses are not matched" );
}
return 0;
}
The program output is
Parentheses are not matched
How should I print StackArray in C?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct
{
void** stackAry;
int count;
int stackMax;
int top;
}STACK;
STACK* createStack(int maxSize)
{
STACK* stack;
stack = (STACK*)malloc(sizeof(STACK));
if(!stack)
return NULL;
stack->count = 0;
stack->top = -1;
stack->stackMax = maxSize;
stack->stackAry = (void**)calloc(stack->stackMax, sizeof(void*));
if(!stack->stackAry)
{
free(stack);
return NULL;
}
return stack;
}
bool pushStack(STACK* stack, void* itemPtr)
{
if(stack->count == stack->stackMax)
return false;
(stack->count)++;
(stack->top)++;
stack->stackAry[stack->top] = itemPtr;
return true;
}
void* popStack(STACK* stack)
{
void* dataPtrOut;
if(stack->count == 0)
dataPtrOut = NULL;
else
{
dataPtrOut = stack->stackAry[stack->top];
(stack->count)--;
(stack->top)--;
}
return dataPtrOut;
}
void* stackTop(STACK* stack)
{
if(stack->count == 0)
return NULL;
else
return stack->stackAry[stack->top];
}
bool emptyStack(STACK* stack)
{
return(stack->top == -1);
}
bool fullStack(STACK* stack)
{
return (stack->count == stack->stackMax);
}
int stackCount(STACK* stack)
{
return stack->count;
}
STACK* destroyStack(STACK* stack)
{
int i;
if(stack)
{
for(i=0 ; i<stack->count ; i++)
free(stack->stackAry[i]);
free(stack->stackAry);
free(stack);
}
return NULL;
}
int main(void)
{
STACK* myStack = createStack(100);
double* ptr;
while(1)
{
ptr = (double*)malloc(sizeof(double));
if(ptr == NULL)
return 0;
else
{
printf("Enter a positive real number: <-1> to stop: \n");
scanf("%lf", ptr);
if(*ptr == -1.0 || fullStack(myStack))
{
break;
}
else
pushStack(myStack, ptr);
}
}
printf("\n\nThe list of numbers reversed: \n");
while(!emptyStack(myStack))
{
ptr = (double*)popStack(myStack);
printf("%lf\n", *ptr);
free(ptr);
}
myStack = destroyStack(myStack);
return 0;
}
When I run the stackAry, the main part doesn't print.
The stack part does not seem to be a problem, but if you print it, "Enter a positive real number: <-1> to stop:" is not printed. If you enter numbers on a blank screen and press -1, it will be printed.
I'm not sure which part is wrong. Please help me
I am trying to implement stack with array in C. But I guess my push function is not correct.(Maybe there are some other mistakes) Because when I run the code, it prints "Stack is empty!" two times.
How can I solve this problem and is this implementation logic is true?
#include <stdio.h>
#define SIZE 10
typedef struct stack
{
int top;
int items[SIZE];
}stack;
void push(int a, stack st)
{
if((st.top + 1) != SIZE)
{
st.top++;
st.items[st.top] = a;
}
else
{
printf("\nStack is full!");
}
}
void pop(stack st)
{
if(st.top != -1)
{
st.top--;
}
else
{
printf("\nStack is empty!");
}
}
void printList(stack st)
{
int i;
for(i = 0; i < st.top + 1; i++)
{
printf("%d -> ", st.items[i]);
}
puts("");
}
int main(void)
{
stack stack1;
stack1.top = -1;
stack stack2;
stack2.top = -1;
push(3, stack1);
push(5, stack1);
push(7, stack1);
printList(stack1);
pop(stack1);
printList(stack1);
pop(stack1);
printList(stack1);
}
Hi your stack implementation is wrong.Using gdb you can verify this.You are passing structure as value you should pass as address.
On gdb you can see
In main
gdb) p &stack1
$4 = (stack *) 0x7fffffffddf0
In push fn
(gdb) p &st
$3 = (stack *) 0x7fffffffdd90
both are different.
correct code is given below.
#include <stdio.h>
#define SIZE 10
typedef struct stack
{
int top;
int items[SIZE];
}stack;
void push(int a, stack *st)
{
if((st->top + 1) != SIZE)
{
st->top++;
st->items[st->top] = a;
}
else
{
printf("\nStack is full!");
}
}
void pop(stack *st)
{
if(st->top != -1)
{
st->top--;
}
else
{
printf("\nStack is empty!");
}
}
void printList(stack *st)
{
int i;
for(i = 0; i < st->top + 1; i++)
{
printf("%d -> ", st->items[i]);
}
puts("");
}
int main(void)
{
stack stack1;
stack1.top = -1;
stack stack2;
stack2.top = -1;
push(3, &stack1);
push(5, &stack1);
push(7, &stack1);
printList(&stack1);
pop(&stack1);
printList(&stack1);
pop(&stack1);
printList(&stack1);
}
just revising C here. I just ran valgrind and it turns out i have memory leaks in my program, even though i free the memory i allocate. What am i missing?
stack.c:
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"
struct node {
int element;
Node *next;
};
struct stack {
Node *tos;
};
Stack *stack_create() {
Stack *S;
if ((S = (Stack *)malloc(sizeof(Stack))) != NULL)
S->tos = NULL;
return S;
}
void stack_destroy(Stack *S) {
Node *temp = S->tos;
while (S->tos != NULL) {
temp = S->tos;
free(S->tos);
S->tos = temp->next;
}
free(S);
}
void push(Stack *S, int element) {
Node *N;
if ((N = (Node *)malloc(sizeof(Node))) != NULL) {
N->element = element;
N->next = (S->tos == NULL) ? NULL : S->tos;
S->tos = N;
}
}
int pop(Stack *S) {
Node *tos = S->tos;
S->tos = tos->next;
return (int) tos->element;
}
int peek(Stack *S) {
return (int) S->tos->element;
}
void to_string(Stack *S) {
Node *cursor = S->tos;
while (cursor != NULL) {
printf("[%d] ", cursor->element);
cursor = cursor->next;
}
printf("\n");
}
int main()
{
Stack *S;
S = stack_create();
push(S, 5);
push(S, 6);
push(S, 4);
push(S, -55);
to_string(S);
printf("Pop %d\n", pop(S));
printf("Pop %d\n", pop(S));
to_string(S);
stack_destroy(S);
return 0;
}
the actual problem is your Pop kills the node, but it doesn't free it
Node* node_destroy(Node* n)
Node* next;
if(n == NULL) return NULL;
next = n->next;
free(n);
return next;
}
int stack_pop(Stack *s) {
int element;
if(s == NULL || s->tos == NULL) return 0; // no really good result you can give
element = s->tos->element;
s->tos = node_destroy(s->tos);
return element;
}
then you can do
void stack_destroy(Stack *S) {
while (S->tos != NULL) {
s->tos = node_destroy(s->tos);
}
free(S);
}
The problem is in your destroy method. You free S->tos which temp refers to. Then you use temp->next.
set temp to S->tos->next.
The problem is with your destory:
void stack_destroy(Stack *S) {
Node *temp = S->tos;
while (S->tos != NULL) {
temp = S->tos;
free(S->tos);
S->tos = temp->next;
}
free(S);
}
Temp is pointing to S->tos from:
temp = S->tos;
But then you immediately free it after:
free(S->tos);
Then when you call the temp->next; temp is already freed.
Try this:
void stack_destroy(Stack *S) {
Node *temp; //Also, no need to assign here from the original (you assign to it immediately within the while)
while (S->tos != NULL) {
temp = S->tos->next; //You need to get the pointer to node "next" before you free S->tos
free(S->tos);
S->tos = temp;
}
free(S);
}
EDIT1: Per Keith Nicholas - See here for his elegant solution
Pop also does not free the node you extract the element from:
old:
int pop(Stack *S) {
Node *tos = S->tos;
S->tos = tos->next;
return (int) tos->element;
}
new:
int pop(Stack *S) {
Node *tos = S->tos;
int element = tos->element;
S->tos = tos->next;
free(tos);
return element;
}