I am trying to create a Stack using an Array. I have made all the necessary functions and I have no errors in the console.
however the output from the printf in the displayStack() is
ê #² ` Ç i i q #╨ #. ` Ç x
how can i fix it ?
my code is :
#include <stdio.h>
#include <stdlib.h>
struct Stack {
int top;
char array[];// Array for stack which will store the operators from infx
};
void createStack(struct Stack st){
st.top=-1;
}
void push(struct Stack st,char ch)
{
st.top++;
st.array[st.top]=ch;
}
void displayStack(struct Stack st){
int i;
for (i=st.top;i>=0;i--){
printf("%c\n",st.array[i]);
}
}
char pop(struct Stack st){
char x='x';
if(st.top<0){
printf("Stack UnderFlow\n");
}else{
x= st.array[st.top];
st.top--;
}
return x;
}
int main()
{
struct Stack st;
createStack(st);
push(st,'x');
push(st,'x');
push(st,'x');
push(st,'x');
push(st,'x');
push(st,'x');
displayStack(st);
pop(st);
return 0;
}
Here:
struct Stack {
int top;
char array[];
};
array can be used as a flexible array member, but you need to malloc with the size of the struct + the number of elements you want to use in the array, i.e.:
data = malloc(sizeof(*data) + nelements);
otherwise the compiler doesn't know how many elements you want to associate to the array
Related
I am not able to initialize all three pointers to struct S, and I don't know why.
I am using a fixed-length array as stack to store values.
The header file is created this way to hide information (struct S), and should be kept as generic as possible.
main.c
// main.c
#include <stdio.h>
#include "stack_exercise4.h"
int main(void) {
Stack *stack_1, *stack_2, *stack_3;
int a, b;
make_empty(stack_1);
make_empty(stack_2);
make_empty(stack_3);
return 0;
}
Problem is, after Stack *stack_1, *stack_2, *stack_3, only stack_2 has a valid address for Struct stack. stack_1 and stack_3 have some strange looking addresses, and I can't assign any values to stack_1->top, nor stack_3->top. What is the problem?
header file
// stack_exercise4.h
#ifndef STACK_EXERCISE4_H
#define STACK_EXERCISE4_H
#include <stdbool.h> /* C99 only */
typedef struct S Stack; /* incomplete type to hide the content
of S. */
void make_empty(Stack *s);
bool is_empty(const Stack *s);
bool is_full(const Stack *s);
void push(Stack *s, int i);
int pop(Stack *s);
#endif
stack source file
// stack_exercise4a.c
#include "stack_exercise4.h"
#include <stdio.h>
#define MAX_STACK_SIZE (10)
struct S {
int top;
int contents[MAX_STACK_SIZE];
};
void make_empty(Stack *s) {
s->top = 0;
}
bool is_empty(const Stack *s) {
return (s->top <= 0);
}
bool is_full(const Stack *s) {
return (s->top >= MAX_STACK_SIZE - 1);
}
void push(Stack *s, int i) {
if (!is_full(s)){
(s->contents)[s->top++] = i;
} else {
printf("Failed to push, Stack is full.\n");
}
}
int pop(Stack *s) {
return (s->contents)[s->top--];
}
The stack pointers must point on memory spaces before being dereferenced in make_empty(). Something like this could be the starting point: make_empty() allocates the memory space.
void make_empty(Stack **s) {
(*s) = (struct S *)malloc(sizeof(struct S));
(*s)->top = 0;
}
And so the initialization of the pointers would be:
make_empty(&stack_1);
make_empty(&stack_2);
make_empty(&stack_3);
Declare stack_X on stack instead.
#include <stdio.h>
#include "stack_exercise4.h"
int main(void) {
Stack stack_1 = {0}, stack_2 = {0}, stack_3 = {0};
int a, b;
make_empty(&stack_1);
make_empty(&stack_2);
make_empty(&stack_3);
return 0;
}
Otherwise, I't would need to have constructor/destructor for your Stack data structure e.g new_stack(Stack *ptr) del_stack(Stack *ptr). For beginner, I would recommend to use stack instead of heap (stay away from malloc).
I'm trying to create a stack in C using structures but the push() function I wrote is acting strangely. I'm sure it is something obvious that I'm missing but I just couldn't figure out what.
#include <stdio.h>
#define STACK_SIZE 50
typedef struct stack
{
int top;
int items[STACK_SIZE];
}
STACK;
void push(STACK* st, int newitem)
{
st->top++;
st->items[st->top] = newitem;
printf("%d", st->items[st->top]);
}
int main()
{
int n = 1;
STACK* st;
printf("test 1\n");
st->top = -1;
push(st, n);
printf("test 2\n");
return 0;
}
DevCpp only compiles but doesn't execute the code. OnlineGDB runs it but only prints the first test.
This is because your variable STACK* st; was never initialized properly.
Some Important Points:
Don't assign -1 to the length (top), 0 would be better
STACK* st; should be just STACK st;
Your function void push(STACK* st, int newitem) should be declared with static linkage.
Write st->top++
Pass st variable by address to the push() function
Instead of using bare return 0;, use return EXIT_SUCCESS;, which is defined in the header file stdlib.h.
As your total STACK_SIZE is only 50 so, int will be sufficient. But as your STACK_SIZE grows use size_t for your length(top).
use int main(void) { }, instead of int main() { }
NOTE: If STACK_SIZE and top becomes equal means your array is filled completely then further addition of data will lead to Undefined Behavior.
Final Code
#include <stdio.h>
#include <stdlib.h>
#define STACK_SIZE 50
typedef struct stack
{
int top;
int items[STACK_SIZE];
}
STACK;
static void push(STACK* st, int newitem)
{
if(st->top == STACK_SIZE)
{
fprintf(stderr, "stack size reached maximum length\n");
exit(EXIT_FAILURE);
}
st->items[st->top++] = newitem;
printf("%d\n", st->items[st->top - 1]); // we added +1 to `top` in the above line
}
int main(void)
{
int n = 1;
STACK st;
printf("test 1\n");
st.top = 0;
push(&st, n); //pass by address
return EXIT_SUCCESS;
}
I am currently writing my own virtual machine. I have to implement the stack. For whatever reason whenever I call sienna_stack_push(processor->stack, 0); it gives me a segfault.
here is the implementation of the stack
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"
// Helper functions
int is_empty(sienna_stack_t* stack){
return stack->top == -1;
}
int is_full(sienna_stack_t* stack){
return stack->top == stack->max_size;
}
void sienna_stack_init(sienna_stack_t* stack, int capacity){
stack = (sienna_stack_t*)malloc(sizeof(sienna_stack_t));
stack->max_size = capacity;
stack->top = -1;
stack->items = (int*)calloc(capacity, sizeof(int));
}
void sienna_stack_push(sienna_stack_t* stack, int value){
if(is_full(stack)){
printf("FATAL: Stack overflow!\n");
exit(-1);
}
stack->items[++stack->top] = value;
}
int sienna_stack_pop(sienna_stack_t* stack){
if(is_empty(stack)){
printf("FATAL: Stack underflow!\n");
exit(-1);
}
return stack->items[stack->top--];
}
int sienna_stack_peek(sienna_stack_t* stack){
return stack->items[stack->top];
}
here is the stack struct definition
typedef struct {
int max_size;
int top;
int* items;
} sienna_stack_t;
here is me using it
#include <stdio.h>
#include "stack.h"
int main() {
sienna_stack_t stack;
sienna_stack_init(&stack, 0xFFFF);
sienna_stack_push(&stack, 0);
}
and the error is saying it is happening when calling sienna_stack_push();
I guess, you want to reserve sizeof(int) * capacity bytes of memory, but in reality you reserve nothing, because the first parameter of calloc() is 0. Thus, you want to access non-reserved memory, that leads to a crash.
EDIT
Your initialisation is wrong. stack is a static variable. When you call init, you pass the address of this variable. Now you assign an new (anonymous) variable that get lost. You could change stack into a pointer variable:
void sienna_stack_init(sienna_stack_t** stack, int capacity){
*stack = (sienna_stack_t*)malloc(sizeof(sienna_stack_t));
(*stack)->max_size = capacity;
(*stack)->top = -1;
(*stack)->items = (int*)calloc(capacity, sizeof(int));
}
// ...
int main(int argc, char *argv[]){
sienna_stack_t *stack;
sienna_stack_init(&stack, 0xFFF);
sienna_stack_push(stack, 0);
}
I am trying to create a stack but I am having a problem initiating it. The code that I have is:
#define LINELN 72
#define STACKSZ 25
#define NEWLN '\n'
#include <stdlib.h>
#include <stdio.h>
// interface struct for stack
typedef struct stack {
char data[STACKSZ];
int top;
} stack;
void initstk(stack *s1);
int emptystk(stack s);
int main() {
stack s1;
initstk(s1);
printf("%d",emptystk(s1));
exit(0);
}
void initstk(stack *s1) {
s1->top=-1;
}
int emptystk(stack s) {
if(s.top == -1){
return 1;
}
else{
return 0;
}
}
I want it to print out 1 since the stack is empty but it is print out 0 still. I don't really understand. Could it be because of the pointer?
You declare:
void initstk(stack *s1);
/*...*/
int main() {
stack s1;
but then you invoke as:
initstk(s1);
Because initstk takes a pointer argument, you should pass the address of s1:
initstk(&s1);
I'm surprised your compiler didn't warn you about the mismatch.
I have a stack implemented with a dynamically allocated array, which is populated using scanf(). The push function works properly, except that when I print out the stack, I always get two extra zeros at the beginning of the output. Attempting to pop the stack only pops the zeroes, and it segfaults once the popping happens twice. I can't figure out where this issue is occurring.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*Creates struct of stack*/
typedef struct Stack{
int *ptArray;
int top;
int stackSize;
int itemsInStack;
} Stack;
/*Initialized stack*/
Stack* stackInit(){
Stack *a;
a= (Stack*) malloc(sizeof(Stack));
a-> ptArray=(int*) malloc(sizeof(int)) ;
a-> top=0;
a-> stackSize=1;
return a;
}
void stackPush( Stack *stx, int val){
if( (stx->top) == (stx->stackSize)){
grow(&stx->ptArray, &stx->stackSize);
}
stx->ptArray[stx->top]= val;
stx->top++;
stx->itemsInStack++;
}
/*Grows astack array when space runs out*/
void grow(int** array, int *sz){
int *temp;
temp= (int*) malloc(sizeof(int)* (*sz+2) );
int i;
for( i=0; i< *sz; i++)
temp[i]=( *array)[i];
free(*array);
*array= temp;
*sz=*sz+2;
}
void stackPop( Stack* stx){
free(stx->ptArray[stx->top]);
stx->top--;
stx->stackSize--;
stx->itemsInStack--;
}
void showStack(Stack* s){
int i;
printf("\n");
for(i=s->stackSize; i>-1; i--){
printf("%d\n", s->ptArray[i]);
}
}
void main(int argc, char** argv){
Stack *stackArray;
stackArray= stackInit();
int val=0;
while (val != -999) {
scanf("%d", &val);
if (val == -999) {
break;
}
stackPush(stackArray, val);
}
showStack(stackArray);
stackPop(stackArray);
stackPop(stackArray);
showStack(stackArray);
stackPop(stackArray);
showStack(stackArray);
}
You have a problem in your malloc / free couples.
You allocate the array like this :
a-> ptArray=(int*) malloc(sizeof(int)) ;
If you need to grow the stack you allocate a new array like this :
temp= (char*) malloc(sizeof(char)* (*sz+2) );
So you allocate the whole array at one.
But for some reasons , when you are poping an item you do this :
free(stx->ptArray[stx->top]);
You never allocated this. you allocated ptArray so if you have to free something , it is ptArray.
Just like you did in your grow function :
free(*array);
I hope your error is clear now.This is what is causing the segmentation fault. However you still have some issues with the management of your stack.