In the following code, I've tried to implement the stack data structure using a linked list. Somewhere in my push function, I assume, I have implemented an improper use of pointers, since, upon execution of code, the compiler throws up a segmentation fault(core dumped)
How do I correct this?
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* nextlink;
};
struct Stack
{
int top;
struct node* head;
struct node* tail;
};
//creates an instance of struct Stack, and return a pointer to it
struct Stack* createStack()
{
struct Stack* stack=(struct Stack*)malloc(sizeof(struct Stack));
stack->head=(struct node*)malloc(sizeof(struct node));;
stack->head->nextlink=NULL;
}
// Stack is empty when head node points to null value
int isEmpty(struct Stack* stack)
{
return stack->head ==NULL;
}
this is my push function.
// Function to add an item to stack. It inserts a node between head pointer, and fist element, and initializes the node that was inserted in between before.
void push(struct Stack* stack, int item)
{
stack->head->data=item;
struct node* intermediate_pointer=(struct node*)malloc(sizeof(struct node));
intermediate_pointer->nextlink=stack->head;
stack->head=intermediate_pointer;
printf("%d pushed to stack\n",item);
}
// Function to remove an item from stack.
void pop(struct Stack* stack)
{
if (isEmpty(stack))
{
printf("warning! stack is empty!\n");
}
else
{
struct node* intermediate_pointer=stack->head;
stack->head=stack->head->nextlink;
free(intermediate_pointer);
}
}
void print_stack(struct Stack* stack)
{
struct node* trans_pointer=stack->head;
while(trans_pointer!=NULL)
{
printf("%d",trans_pointer->data);
trans_pointer=trans_pointer->nextlink;
}
}
//function to respond to user's choice of operation
void stackoper_imp(int ch, struct Stack* stack)
{
if(ch==1)
{
int ele;
printf("enter the integer element you want to push on top of the stack:");
scanf("%d",&ele);
push(stack,ele);
print_stack(stack);
}
else if(ch==2)
{
pop(stack);
print_stack(stack);
}
else
{
return;
}
}
int main()
{
int choice;
struct Stack* stack = createStack();
while(choice!=3)
{
printf("which operation do you want to perform on your stack?\n1.push\n2.pop\n3.exit\n");
scanf("%d",&choice);
stackoper_imp(choice, stack);
}
}
CodePudding user response:
struct Stack* createStack() { struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack)); stack->head = (struct node*)malloc(sizeof(struct node));; stack->head->nextlink = NULL; }
This is declared as returning struct Stack *
, but then you don't return stack
: the pointer to the struct Stack
you've created.
struct Stack* createStack()
{
struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->head = (struct node*)malloc(sizeof(struct node));;
stack->head->nextlink = NULL;
return stack;
}
Even with this you risk a segmentation fault as malloc
doesn't have to succeed. You'd want to check the return value of it before trying to access member fields.
struct Stack* createStack()
{
struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
if (!stack) return NULL;
stack->head = (struct node*)malloc(sizeof(struct node));;
if (!stack->head) return NULL;
stack->head->nextlink = NULL;
return stack;
}
And then obviously when you use createStack
you'll want to check to ensure it did not return NULL
.
CodePudding user response:
createStack()
does not return a pointer to the stack you created, it does not return anything.
You need to return the pointer to the stack by adding: return stack
struct Stack* stack= malloc(sizeof(struct Stack));
if(stack == NULL)
{
fprintf(stderr, "Failed to allocate memory for stack\n");
return NULL;
}
struct node* head = malloc(sizeof(struct node));;
stack->head = head;
if(head == NULL)
{
fprintf(stderr, "Failed to allocate memory for node\n");
return NULL;
}
stack->head->nextlink=NULL;
return stack;
Also, malloc()
can fail, so you need to check to ensure that it does not return a NULL
pointer as that will result in undefined behavior. However you want to handle these errors outside of the function is entirely up to you.