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.
Related
This question already has answers here:
Why does call-by-value example not modify input parameter?
(6 answers)
How to modify a struct in a function and return to main?
(2 answers)
Closed 10 months ago.
I'm learning Data Structures and was implementing a stack on C. The code compiles correctly but the stack remains unedited i.e. nothing is being pushed into the stack even after a push operation and it stays empty. I'm not sure where the problem with this code is. Please help me with this. Thanks.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 101
//Define a struct
struct stack{
int A[MAX_SIZE]; //Array of size 101
int top; //Variable that stores the index position of the recently inserted element in the stack.
};
//Function to create a stack, set top to -1 and return it.
struct stack CreateStack(){
struct stack p;
p.top = -1;
return p;
}
//Function to insert a number at the end of the stack.
void Push(int x, struct stack p){
//If the array is full, return an error message.
if (p.top == MAX_SIZE - 1){
printf("Error: Stack Overflow!");
return;
}
//Increment top and set insert x at the last of A.
p.top++;
p.A[p.top] = x;
};
//Function to delete an element from the last in a stack.
void Pop(struct stack p){
//If stack is already empty, print a message.
if (p.top == -1){
printf("Empty Stack!");
return;
}
//Decrement top.
p.top--;
};
//Function to return the top element in the stack.
int Top(struct stack p){
return p.A[p.top];
};
//Function to check if the stack is empty.
int IsEmpty(struct stack p){
return p.top == -1;
};
//Function to display all the elements in the stack.
void Print(struct stack p)
{
printf("Stack: ");
for(int i = 0; i <= p.top; i++){
printf("%d", p.A[i]);
}
printf("\n");
};
int main(){
struct stack mystack = CreateStack(); //Creates a stack called mystack.
Push(22, mystack); //Pushes 22 on the stack.
Print(mystack);// Should display 22.
}
You pass struct stack p by value (copy); instead pass it in via pointer so the modifying functions can change state:
void Push(int x, struct stack *p,) {
if (p->top == MAX_SIZE - 1){
printf("Error: Stack Overflow!");
return;
}
p->A[p->top++] = x;
};
It's a convention to pass the abstract data type (here struct stack *p) as the first argument. Also consider returning a status so caller can tell if the function failed. Finally, it's a good idea to separate i/o (printing error messages) from logic, as it may depend on the context of the caller (console/browser/gui, but also it may not be an error for caller if the stack is full). For example:
struct stack *Push(struct stack *p, int x) {
if (p->top == MAX_SIZE - 1) return NULL;
p->A[p->top++] = x;
return p;
};
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.
This question already has answers here:
Difference between null pointers and uninitialized pointers?
(5 answers)
Closed 1 year ago.
I am trying to implement stack in C. I am not getting any compilation error but I am getting the return value as 322122547 without any error. What should I do ?
Here is my code
#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 isFull(struct stack * ptr)
{
if (ptr->top == ptr->size - 1)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
struct stack *s;
s->size = 10;
s->top = -1;
s->arr = (int *)malloc(s->size * sizeof(int));
if(isEmpty(s)){
printf("The stack is empty");
}
else{
printf("The stack is not empty");
}
return 0;
}
If I use a struct stack pointer I do not get any output. Should I consider changing the pointer part
Turn on your compiler errors and it will tell you right away what's wrong. For example if I compile your code with gcc -Wall -Werror it says:
error: 's' is used uninitialized [-Werror=uninitialized]
s->size = 10;
| ~~~~~~~~^~~~
Problem origin
struct stack *s; is defining a pointer that is expecting an instance of your structure. Now by default, that expected structure is not initialized and therefore the pointer points to a random location in memory.
You can visualize this error by using gcc -Wall -Werror the compiling and you get:
error: 's' is used uninitialized [-Werror=uninitialized]
s->size = 10;
| ~~~~~~~~^~~~
Since the location the pointer is pointing to is random, you will get random values from your pointer depending on what that memory location contains.
A solution
A way to fix this is to initialize the structure your pointer is expecting to point to in order to allocate this structure. You can do this in two way:
Static allocation: you can create a structure and then point to it using:
struct stack s_static;
struct stack *s = &s_static;
The final code would be:
int main()
{
struct stack s_static;
struct stack *s = &s_static;
s->size = 10;
s->top = -1;
s->arr = (int *)malloc(s->size * sizeof(int));
if(isEmpty(s)){
printf("The stack is empty");
}
else{
printf("The stack is not empty");
}
return 0;
}
Dynamic allocation: you can dynamically allocate your structure in memory by using malloc. You can allocate your stack instance s by doing struct stack* s = (struct stack*) malloc(sizeof(struct stack));. This is a big line. What's happening? struct stack* s tells the compiler this is a pointer that is pointing to a memory location. (struct stack*) is telling the malloc that the new memory location we're about to allocate has type struct stack. Finally, malloc creates some space on the heap for our instance and sizeof(struct stack) simply tells the malloc command how much memory we need to allocate. After putting this line, the code will compile without errors.
BUT WAIT! If you use dynamic allocation, you need to also free the heap once you finish, otherwise the memory location will leak. Therefore, before your return 0, you need to free that memory location. You can do so by using free(s)
The final dynamic allocation approach will look something like this:
int main()
{
struct stack* s = (struct stack*) malloc(sizeof(struct stack));
s->size = 10;
s->top = -1;
s->arr = (int *)malloc(s->size * sizeof(int));
if(isEmpty(s)){
printf("The stack is empty");
}
else{
printf("The stack is not empty");
}
free(s);
return 0;
}
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.
I get a segfault while runnig this code to implement a stack in C. Please note that the code is kind of incomplete. I just wanted to check and see if I could push a few elements on to the stack and print them out. But it throws back a segfault. Any help would be much appreciated!!
#include<stdlib.h>
#include<stdio.h>
struct stack
{
int *elems;
int ll;
int al;
};
void stack_new(struct stack *s)
{
s->ll=0;
s->al=4;
s->elems=malloc(4*sizeof(int));
}
void stack_del(struct stack *s)
{
free(s->elems);
}
void stack_push(struct stack *s,int value)
{
if(s->ll==s->al)
{
printf("overflow");
/*s->al*=2;
s->elems=realloc(s->elems, s->al*sizeof(int));*/
}
s->elems[s->ll]=value;
s->ll++;
}
void stack_pop(struct stack *s)
{
s->ll--;
return (s->elems[s->ll]);
}
void main()
{
struct stack *s;
stack_new(s);
stack_push(s,3);
stack_push(s,4);
stack_push(s,8);
printf("%d", s->elems[0]);
//stack_pop(s);
//stack_del(s);
}
Declaring
struct stack *s;
doesn’t allocate any memory for a struct stack. Do that:
struct stack *s = malloc(sizeof *s);
Or just put your stack on the stack:
struct stack s;
stack_new(&s);
…
Using more descriptive field names is also a good idea.
You have several errors
You never initialize the pointer s in your main function, so in your stack_new function dereferencing s causes a segmentation fault.
You should allocate space for the stack first, wherever you want but you must.
Another thing is if you want to initialize your al field with a constant number and then allocate an array of constant size, you don't need the field al, and you can declare elems as int elems[CONSTANT_NUMBER] but if you want it to be dynamic, which is what I think you want from your check if(s->ll == s->al) in the stack_push function, then you can simply pass the value you want al to have to the stack_new function.
This is some of your code, fixed so you can see what I actually mean.
#include<stdlib.h>
#include<stdio.h>
struct stack
{
int *elems;
int ll;
int al;
};
struct stack *stack_new(int al) /* you can pass the maximum number of elements allowed */
{
struct stack *s;
s = malloc(sizeof(struct stack));
if (s == NULL)
return NULL;
s->ll = 0;
s->al = al;
s->elems = malloc(al * sizeof(int)); /* and you dynamically allocate space for them here */
return s;
}
void stack_del(struct stack *s)
{
if (s != NULL) /* always check the pointers to prevent `SEGMENTATION FAULT` */
{
if (s->elems != NULL)
free(s->elems);
free(s);
}
}
void stack_push(struct stack *s, int value)
{
if (s == NULL)
return;
if(s->ll == s->al)
{
printf("overflow");
/*s->al*=2;
s->elems=realloc(s->elems, s->al*sizeof(int));*/
}
if (s->elems != NULL)
s->elems[s->ll] = value;
s->ll++;
}
int stack_pop(struct stack *s)
{
if ((s == NULL) || (s->elems == NULL))
return 0;
s->ll--;
return (s->elems[s->ll]);
}
int main()
{
struct stack *s;
s = stack_new(4);
stack_push(s, 3);
stack_push(s, 4);
stack_push(s, 8);
printf("%d", s->elems[0]);
stack_pop(s);
stack_del(s);
return 0;
}
```