I am new at C programming. I wrote some code for a stack exercise. The question is: one of the result is wrong, but when I debug step by step, the number changed abruptly. Could you help me solve this?
// #name mystack.c
// Created by lilei on 2017/3/10.
//
#include "mystack.h"
#include <malloc.h>
#include <stdio.h>
Stack createStack(){
Stack stack = (Stack)malloc(sizeof(Stack));
stack->top = -1;
return stack;
}
int isFull(Stack s){
if (s->top == MAXSIZE-1){
return 1;
} else{
return 0;
}
}
int push(Stack s, ElementType item){
if(!isFull(s)){
s->top++;
s->data[s->top] = item;
return 1;
} else{
printf("full!");
return 0;
}
}
int isEmpty (Stack s){
if(s->top == -1){
return 1;
} else{
return 0;
}
}
ElementType pop(Stack s){
if(!isEmpty(s)){
ElementType e = s->data[s->top];
s->top--;
return e;
}
}
void myPrintf(Stack s){
int len = s->top;
printf("The data are ");
while(len >= 0){
printf("%d ", s->data[len]);
len--;
}
printf("\n");
}
int main(){
Stack s = createStack();
for(int i = 0; i < 7; i++){
push(s, i*2);
}
myPrintf(s);
printf("isEmpty:%d, isFull:%d\n, pop one:%d", isEmpty(s), isFull(s), pop(s));
}
The result is
I can't see the declaration of Stack because you forgot to put it in th question, but it must be declared as a pointer to a struct e.g.
typedef struct
{
int top;
ElementType data[MAXSIZE];
} *Stack;
// ^- means pointer
So a Stack is a pointer type which means that, when you malloc it, you malloc only 4 or 8 bytes depending on whether you are compiling for 32 or 64 bit. The malloc line should be
Stack stack = malloc(sizeof *stack);
You were not allocating enough space on your stack for the actual stack structure which means that you are writing into bits of the heap you do not own and other things will write into the memory you think you have allocated for your stack.
There is another problem. What does your pop() function return if you try to pop something when the stack is empty? The answer is "could be anything". You either need to abort the program or return some error value.
Related
I am learning Stack in C and try to implement stack using array in C. This code I am using from https://codewithharry.com/videos/data-structures-and-algorithms-in-hindi-24
I create struct stack below.
In the main , I create a struct stack s and assign a value of 10. While executing the code, there is segmentation fault happened. I tried to lldb in VS code. it shows below error.
Please help me how to fix this code segmentation fault. What is the reason for segmentation fault?
Exception has occurred. EXC_BAD_ACCESS (code=1, address=0x25)
#include<stdio.h>
#include<stdlib.h>
// creating stack
struct stack
{
int size; //store the size of stack
int top; //store index of top most element
int *arr; //to hold the address of the array
};
// Check if stack is empty
int isEmpty(struct stack *ptr)
{
if (ptr->top == -1){
return 1;
}
else{
return 0;
}
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size - 1)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
struct stack *s;
s->size = 10; // This line has exception occured with EXC_BAD_ACCESS (code=1, address=0x25)
s->top = -1;
s->arr = (int *)malloc(s->size * sizeof(int)); //reserve memory in heap
// Check if stack is empty
if(isEmpty(s)){
printf("The stack is empty");
}
else{
printf("The stack is not empty");
}
// Pushing an element manually
s->arr[0] = 7;
s->top++;
// Check if stack is empty
if(isEmpty(s)){
printf("The stack is empty");
}
else{
printf("The stack is not empty");
}
return 0;
}
This is wrong
struct stack *s;
s->size = 10;
s is a pointer to a stack. What stack object is it pointing at, none, hence the error. You have to create an stack and point at it, or use one directly.
struct stack *s = malloc(sizeof(struct stack));
s->size = 10;
or
struct stack s;
s.size = 10;
The second one creates a stack object on the stack.
my code is not working but when I change struct stack *sp; to struct stack * sp = (struct stack *) malloc(sizeof(struct stack)); it start working. I am confused in when to allocate memory in heap to struct stack *ptr and when to not. It will be better if u can give me an example when struct stack *ptr can be used and when to use struct stack * sp = (struct stack *) malloc(sizeof(struct stack));
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stack
{
int size;
int top;
char *arr;
};
int stackTop(struct stack* sp){
return sp->arr[sp->top];
}
int isEmpty(struct stack *ptr)
{
if (ptr->top == -1)
{
return 1;
}
else
{
return 0;
}
}
int isFull(struct stack *ptr)
{
if (ptr->top == ptr->size - 1)
{
return 1;
}
else
{
return 0;
}
}
void push(struct stack* ptr, char val){
if(isFull(ptr)){
printf("Stack Overflow! Cannot push %d to the stack\n", val);
}
else{
ptr->top++;
ptr->arr[ptr->top] = val;
}
}
char pop(struct stack* ptr){
if(isEmpty(ptr)){
printf("Stack Underflow! Cannot pop from the stack\n");
return -1;
}
else{
char val = ptr->arr[ptr->top];
ptr->top--;
return val;
}
}
int precedence(char ch){
if(ch == '*' || ch=='/')
return 3;
else if(ch == '+' || ch=='-')
return 2;
else
return 0;
}
int isOperator(char ch){
if(ch=='+' || ch=='-' ||ch=='*' || ch=='/')
return 1;
else
return 0;
}
char* infixToPostfix(char* infix){
struct stack *sp;
sp->size = 10;
sp->top = -1;
sp->arr = (char *) malloc(sp->size * sizeof(char));
char * postfix = (char *) malloc((strlen(infix)+1) * sizeof(char));
int i=0; // Track infix traversal
int j = 0; // Track postfix addition
while (infix[i]!='\0')
{
if(!isOperator(infix[i])){
postfix[j] = infix[i];
j++;
i++;
}
else{
if(precedence(infix[i])> precedence(stackTop(sp))){
push(sp, infix[i]);
i++;
}
else{
postfix[j] = pop(sp);
j++;
}
}
}
while (!isEmpty(sp))
{
postfix[j] = pop(sp);
j++;
}
postfix[j] = '\0';
return postfix;
}
int main()
{
char * infix = "x-y/z-k*d";
printf("postfix is %s", infixToPostfix(infix));
return 0;
}
Two things to always remember when working with pointers in C:
Memory allocation is your problem. You have to think about the allocation of the memory which a pointer variable points to.
You have to be clear in your mind about the distinction between the pointer versus the data that it points to.
So when you say
struct stack *sp;
that will never work, all by itself. It won't work for a program that's implementing a stack, and it won't work for a program that's implementing any other kind of data structure.
When you write
struct stack *sp;
there is one important thing that you have done, and there is one important thing that you have not done.
The compiler allocates space to store one pointer. This pointer is known as sp. But:
The value of this pointer is indeterminate, which means that it does not point anywhere yet. You can't actually use the pointer variable sp for anything. (Yet.)
Or, in other words, going back to the distinction I mentioned earlier, you have taken care of the pointer but you don't have any data that the pointer points to.
But when you say
sp = malloc(sizeof(struct stack));
(and assuming malloc succeeds), now sp points somewhere: it points to a chunk of properly-allocated memory sufficient to hold one struct stack.
This is the code here. Even after debugging I'm not able to find the problem. The code was working fine if I'm not using the pointer.
#include <stdio.h>
#include <stdlib.h>
struct stack{
int size;
int top;
int *arr;
};
int isEmpty(struct stack *ptr){
if ((*ptr).top == -1){
return 1;
}
else{
return 0;
}
}
int main()
{
struct stack *s;
(*s).size = 80;
(*s).top = -1;
(*s).arr = (int *)malloc((*s).size * sizeof(int));
// Check if stack is empty
if(isEmpty(s)){
printf("The stack is empty");
}
else{
printf("The stack is not empty");
}
return 0;
}
You did not allocate any memory for your struct. You may decalre it on the stack: struct stack s; or allocate memory for it: struct stack *s = (struct stack *)malloc(sizeof(struct stack));.
When you have a pointer to a struct, please use the -> operator to access its members like so s->size.
I made a stack and i am using the isEmpty function but the output is not coming. I trued manually using the gcc command and also using the code runner extension.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack
{
int top;
int size;
int *arr;
} Stack;
int isEmpty(Stack *st)
{
if (st->top == -1)
{
return 1;
}
else
{
return -1;
}
}
int main()
{
Stack *st;
st->top = -1;
st->size = 10;
st->arr = (int *)malloc(st->size * sizeof(int));
int i = isEmpty(st);
if (i == 1)
{
printf("The stack is empty\n");
}
else
{
printf("The stack is not empty\n");
}
return 0;
}
The file is named Stack.c.
There is one more thing that the basic hello world program is working perfectly
Stack *st;
st->top = -1;
You invoked undefined behavior by accessing uninitialized pointer st->top = -1;.
You should initialize st first:
Stack *st = malloc(sizeof(Stack));
I tried implementing Dynamic array in C, where size is doubled every time stack is found to be full. When I try to push more than 8 elements, it fails. Output it gave was:
stack empty (since nothing is pushed on to it yet)
|1|
yes (indicates: double operation called)
|2|
yes
|3|
|4|
yes
|5|
|6|
|7|
|8|
yes
Can anyone explain why does it work only for size of stack up to 8 (n<=8, in main)
Thanks
code:
#include
#include
struct stkarr{ //structure for a node
int top;
int capacity;
int *arr;
};
struct stkarr* buildstk(){ //build an object stack (s)
struct stkarr *s = (struct stkarr*)malloc(sizeof(struct stkarr));
// since it's a dynamic array we start with capacity = 1
s->capacity=1;
s->top=-1;
s->arr = (int*)malloc(s->capacity*sizeof(int));
return s;
};
int is_stk_full(struct stkarr* s){
return(s->top==s->capacity-1); // 1->yes, 0->no
}
int is_stk_empty(struct stkarr* s){
return(s->top==-1);
}
void dbl_stk(struct stkarr *s){//doubling the size of stack
(s->capacity)*=2;
s->arr = realloc(s->arr,s->capacity);
}
void psh(struct stkarr* s,int val){ //push
if(is_stk_full(s)){
printf("yes\n");
dbl_stk(s);
}
s->arr[++s->top] = val;
}
int pop(struct stkarr* s){
if(is_stk_empty(s)){
printf("stack empty\n");
return;
}
else{
return s->arr[s->top--];
}
}
int main(){
struct stkarr* s;
int i,n;
n=10;
s = buildstk();
//checking empty stack exception
pop(s);
for(i=0;i<n;i++){
//push operation
psh(s,i+1);
printf("|%d|\n",pop(s)); // just checking if i+1 is pushed or not
psh(s,i+1); // since I popped i+1, pushing it again on to stack
}
//never reaches here for n>8
for(i=0;i<n;i++){//popping elements and printing them
//pop operation
printf("|%d|\n",pop(s));
}
return 0;
}
Your buffer isn't big enough. realloc(s->arr,s->capacity); should be realloc(s->arr,s->capacity * sizeof(int));