Creating pointer to a typedef stack - c

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).

Related

I'm trying to create a stack in c using structures but my push function doesn't work

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;
}

Stack implementation is giving Segfault

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);
}

displayStack function printing random letters

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

C - Cannot get stack to initiate in my program

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.

why do you need to include stack.h in stack.c?

the implementation level of the array-based
#include "stack.h"
void creat_stack(Stack *s) {
s->Top = 0;
}
int isFull(Stack s) {
return (s.Top == Max ? 1 : 0);
}
int isEmpty(Stack s) {
return (s.Top == Max ? 1 : 0);
}
void push(stack_entry e, Stack *s) {
if (!isFull(*s))
s->entry[s->Top++] = e;
else
printf("Error : Stack Overflow\n");
}
void pop(stack_entry *e,Stack *s) {
if(!isEmpty(*s))
*e = s->entry[s->Top--];
else
printf("Error : Stack Underflow\n");
}
the header file stack.h that consists of the prototypes of the functions along with the definition of the stack element type stack_entry.
#pragma once
#include <stdio.h>
#define Max 10
typedef char stack_entry;
typedef struct Stack{
int Top;
stack_entry entry[Max];
}Stack;
void creat_stack(Stack *s);
int isFull(Stack s);
int isEmpty(Stack s);
void push(stack_entry e,Stack *s);
void pop(stack_entry *e, Stack *s);
so my question why i have to include the header file "stack.h" in the "stack.c" file ??
You should have to add the stack.h because this file is it who has all declarations of your typedef define struct and methods
So without then, will be impossible to access any of those informations.
It is the same if you declare a method below the main function and do not declare his signature upstairs the main, you cannot access..
So, all this happens with all include files that you use at the top of your file..
Do not forget C is a sequential language, so you will never know what do you have in the next line if you don't tell the compiler.
check more here
First, don't include "stdio.h" in the header file, you aren't use it there anyway. include it in the source file where you are using it.
You need to include the header file for the "struct stack" and the "define".

Resources