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);
}
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 trying to fill a stack (reserved by malloc) with the value 0xAA or 0b10101010. I think I manage to fill the stack, but printing it, I get different outputs (e83e83e83... or 41f41f41f... for example) depending on my stacksize.
Does anyone have an idea how to solve the problem?
int main(void) {
int status;
int stacksize = 1000;
void* stack=malloc(stacksize);
void* stackTop = stack + stacksize;
for(int i =0; i<stacksize;i++){
stackTop = "10101010";
stackTop --;
}
stackTop =stack + stacksize;
for(int i =0; i<stacksize;i++){
printf("%x", stacksize);
}
return 0;
}
It's somewhat hard to understand from your code and comments, what you're actually trying to do. But if I were to extrapolate on it, you're trying to create a "stack", with an element size of a byte. Here's a quick-and-dirty implementation of such a stack, with bounds checking:
#include <stdio.h>
#include <string.h>
#define STACK_SIZE 1000
struct stack {
int top;
unsigned char elts[STACK_SIZE];
};
static void stack_push(struct stack *s, unsigned char elt) {
if (s->top < STACK_SIZE-1) {
s->elts[s->top++] = elt;
} else {
// No space left in the stack.
}
}
static void stack_pop(struct stack *s) {
if (s->top) {
s->top--;
} else {
// Stack is empty
}
}
static void stack_fill(struct stack *s, unsigned char v) {
memset(s->elts, v, STACK_SIZE);
s->top = STACK_SIZE-1;
}
int main(void) {
// Example driver
struct stack s;
stack_fill(&s, 0xAA);
for (int i = 0; i < STACK_SIZE; i++) {
printf("%d: %02x\n", s.elts[s.top]);
stack_pop(&s);
}
return 0;
}
As an improvement, you could consider e.g. having stack_pop return the popped element, or return some kind of an error if the stack is empty. Or a peek function which returns the top, or an error similar to the one earlier described. However, I omitted them for brevity.
EDIT: To initialize the stack, the only thing required is to set the top member to 0. Initialization function (if needed) is thus trivial to write.
You are filling the stack with strings of chars and reading pointers to them.
The answer given by Paul Hankin in the comment states one of the correct solutions that is using
memset(stack, 0xAA, stacksize);
to fill your stack
thus producing the following code
int main()
{
int status;
int stacksize = 1000;
void* stack = malloc(stacksize);
void* stackTop = stack + stacksize;
memset(stack, 0xAA, stacksize);
for(int i =0; i < stacksize;i++){
printf("%x\n", ((unsigned char*)stack)[i]);
}
return 0;
}
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
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.