Why are all elements replaced in stack after new one added? - c

Simple stack implementation in C:
struct Stack {
char* data;
Stack* prev;
};
void push(char* data, Stack** stack) {
Stack* node = (Stack*)malloc(sizeof(Stack));
node->data = data;
node->prev = *stack;
*stack = node;
}
int main() {
Stack* top = NULL;
push("1", &top);
push("2", &top);
push("3", &top);
}
then top->prev->prev->data results into 3 same as top->prev->data and top->data.
Can anybody explain why?

So, it appears to work correctly.
#include <stdlib.h>
#include <stdio.h>
struct Stack {
char* data;
struct Stack* prev;
};
void push(char *data, struct Stack** stack) {
struct Stack* node = malloc(sizeof(struct Stack));
node->data = data;
node->prev = *stack;
*stack = node;
}
int main() {
struct Stack* top = NULL;
push("1", &top);
push("2", &top);
push("3", &top);
printf("top->data: %s\n", top->data);
printf("top->prev->data: %s\n", top->prev->data);
printf("top->prev->prev->data: %s\n", top->prev->prev->data);
}
The output is:
top->data: 3
top->prev->data: 2
top->prev->prev->data: 1

Related

Error in creating stack header file. In C

#include <stdbool.h>
#include <stdlib.h>
typedef struct Node{
void *data;
struct Node *next;
}node;
typedef struct Stack{
node *top;
}stack;
bool push (stack *s , void *val)
{
node *n;
n = create_node (val);
if (n)
{
n->next = s->top;
s->top = n;
return true;
}
return false;
}
void* pop (stack *s)
{
node *temp;
void *x = NULL;
if (s->top)
{
x = s->top->data;
temp = s->top;
s->top = s->top->next;
free(temp);
}
return x;
}
void* peek (stack *s)
{
void *x = NULL;
if (s->top)
x = s->top->data;
return x;
}
node* create_node (void *val)
{
node *n;
n = (node*) malloc (sizeof(node));
if (n)
{
n->data = val;
n->next = NULL;
}
return n;
}
stack* create_stack (void)
{
stack *s;
s = (stack*) malloc (sizeof(stack));
if (s)
s->top = NULL;
return s;
}
I tried to write a header file for stack in C. I included this header file in another program. I added the header file #include"mystack.h"
I think the error is somewhere in passing void pointer but I don't know how to debug it.
The stack gets created successfully but as I try to push or pop the code terminates. I can't seem to find the error.
The code for calling program is,
#include <stdio.h>
#include <stdbool.h>
#include "mystack.h"
void main()
{
stack *s = NULL;
int *x;
int val;
bool res;
s = create_stack ();
printf ("Enter value to push : ");
scanf ("%d" , val);
res = push (s , &val);
if (res)
printf ("...PUSHED %d IN STACK...\n", *x);
else
printf ("...STACK OVERFLOW...\n");
free(s->top);
free(s);
}
The code stops after push operation is called.

What is wrong in the stack implementation using linked lists?

I am trying to implement a stack using linked list. Here is my code:
#include<stdio.h>
//implementation of stack
struct Node{
int data;
struct Node* next;
struct Node* prev;
};
struct Stack{
struct Node* headNode;
struct Node* presentNode;
int size;
};
struct Node* newNode()
{
struct Node* node;
return node;
}
struct Stack* newStack()
{
struct Stack* stack;
stack->headNode = newNode();
stack->presentNode = stack->headNode;
stack->size=0;
return stack;
}
int isempty(struct Stack* s)
{
if(s->headNode->next != NULL)
return 0;
return 1;
}
void push(struct Stack* s,int data)
{
struct Node* node = newNode();
node->data = data;
node->next = NULL;
s->presentNode->next = node;
node->prev = s->presentNode;
s->presentNode = node;
s->size ++;
}
int pop(struct Stack*s)
{
if(isempty(s)==1)
return 0;
int data = s->presentNode->data;
s->presentNode->prev->next = NULL;
s->presentNode = s->presentNode->prev;
s->size --;
return data;
}
int main()
{
struct Stack* stack = newStack();
int data = 0,type;
printf("Enter '1' if new element to be added or '0' if the latest element is to be deleted.\n");
while(data!=-1)//unbounded stack
//takes input until data==-1
{
scanf("%d",&type);
if(type)
{
printf("Enter the element:\t");
scanf("%d",&data);
if(data==-1)
continue;
push(stack,data);
}
else
printf("%d is popped out of the list!\n",pop(stack));
}
return 0;
}
But I am getting run-time error. Since I am new to pointers (I am a Java guy), I am pretty confused where my error is, although I am sure it is due to pointers.
You do not allocate memory for your new nodes:
struct Node* newNode()
{
struct Node* node;
return node;
}
Local variable node is an uninitialized pointer. As soon as you use the return value of this function, you have Undefined Behaviour.
Edit:
The same problem is true for newStack:
struct Stack* newStack()
{
struct Stack* stack;
stack->headNode = newNode();
...
return stack;
}
As soon as you dereference stack, you have Undefined Behaviour.
You have multiple problems. For starters
In your newStack() function, you do not have a return statement, so using the return value causes undefined behavior.
You need to allocate memory to pointers (i.e., make pointers to point to valid memory) before you can actually dereference them. In your case
struct Stack* stack;
stack->headNode
is an attempt to use uninitialized memory which again causes UB.

Palindrome LinkedList

Method:
Traverse the given list from head to tail and push every visited node to stack.
Traverse the list again. For every visited node, pop a node from stack and compare data of popped node with currently visited node.
If all nodes matched, then return true, else false.
Edit: The program compiles without an error but stops working during run time
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
struct Node
{
int data;
struct Node *next;
};
struct Stack
{
unsigned capacity;
int top;
int * array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack=(struct Stack*)malloc(sizeof(struct Stack));
stack->capacity=capacity;
stack->top=-1;
stack->array=(int *)malloc(sizeof(int)*stack->capacity);
return stack;
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// stack.
void push(struct Stack* stack, int item)
{
if (isFull(stack))
return;
stack->array[++stack->top] = item;
printf("%d pushed to stack\n", item);
}
// stack.
int pop(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top--];
}
// stack
int peek(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top];
}
// linkedlist
void insert(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp)
{
push(stack,temp->data);
temp=temp->next;
}
while(curr)
{
if(pop(stack)==curr->data)
{
curr=curr->next;
}
else
exit(0);
}
return true;
}
// Driver program to test above functions
int main()
{
struct Stack* stack = createStack(100);
struct Node* head=NULL;
insert(&head,1);
insert(&head,2);
insert(&head,1);
printf("%s",compare(stack,head));
return 0;
}
Function compare has at least two errors. The first one is that it uses uninitialized pointer temp
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // <= temp is not initialized
{
The second one is that the function never returns false though according to the assignment it has to return false if values in the list and in the stack do not match.
Instead of returning false you call function exit
else
exit(0);
I would write the function the following way
bool compare(struct Stack *stack, struct Node *head )
{
struct Node *current = head;
for ( ; current != NULL && !isFull( stack ); current = current->next )
{
push( stack, current->data );
}
current = head;
while ( current != NULL && !isEmpty( stack ) && pop( stack ) == current->data )
{
current = current->next;
}
return current == NULL && isEmpty( stack );
}
It is the only correct function implementation among presented here function implementations in other answers.:)
As C does not have type bool then that you could use name bool in a program written in C you have to include header <stdbool.h> or define this name yourself as a typedef either of _Bool (if your compiler supports this type) or of int.
You could declare the return type of the function as int if you do not want to include header <stdbool.h>. For example
int compare(struct Stack *stack, struct Node *head );
Take into account that you need to write also functions that will free all allocated memory for the list and the stack.
For example you could free memory allocated for the stack the following way
void freeStack( struct Stack **stack )
{
if ( *stack != NULL ) free( ( *stack )->array );
free( *stack );
*stack = NULL;
}
The same way you could free the memory allocated for the list
void freeList( struct Node **head )
{
if ( *head != NULL )
{
Node *current = ( *head )->next;
while ( current != NULL )
{
Node *temp = current;
current = current->next;
free( temp );
}
}
free( *head );
*head = NULL;
}
struct Node* temp;
temp is not initialized in
bool compare(struct Stack* stack,struct Node* head)
struct Node* temp,* curr=head;
is not
struct struct Node* temp=head,* curr=head;
Using uninitialized variables lead to undefined behavior.
You've got an uninitialized local variable temp:
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // NOT INITIALIZED
{
push(stack,temp->data);
temp=temp->next;
}
while(curr)
{
if(pop(stack)==curr->data)
{
curr=curr->next;
}
else
exit(0);
}
return true;
}
You need to fix that first; I think the following should work:
bool compare(struct Stack* stack,struct Node* head)
{
struct Node *curr;
for (curr = head; curr != NULL; curr = curr->next)
{
push(stack, curr->data);
}
for (curr = head; curr != NULL; curr = curr->next)
{
if (pop(stack) != curr->data)
return false;
}
return true;
}
Next, you're printing a boolean result with "%s", which is for strings. You need to do something like:
c=compare(stack,head);
printf("%d\n", c);
or alternatively
printf("%s\n", c ? "true" : "false");
At this point, it no longer crashes for me, and works for a couple simple test cases. You might think about how to handle the case of overflowing the stack, and also consider formatting your code to make it more readable.
bool compare(struct Stack* stack,struct Node* head) {
struct Node* temp=head;//<- Needs initialising. It wasn't.
struct Node* curr=head;
while(temp) {
push(stack,temp->data);
temp=temp->next;
}
while(curr) {
if(pop(stack)==curr->data) {
curr=curr->next;
} else {
//exit(0); <--Some mistake surely!
return false; //Slightly less drastic!
}
}
return true;
}
It's slightly a matter of taste but I find long series of variable declarations to be difficult to read and hence error-prone.
You only really need one local variable - but your compiler probably optimizes that away.
exit(0) will abruptly end the program. Most likely indicates 'success' (the exit of 0).
You should return false;.
PS: Credit for using #include <stdbool.h>.

Empty stack of linked list

I am trying to figure the way to empty stack for linked list. I found a way but this way is only work for array stack
void empty(StackPtr S)
{
S -> top = -1;
}
my guess is to use
while(!isEmpty(s))
which the function isEmpty will check if the stack is empty or not. Then I'm stuck :(
Edit:
The way I push it:
void push(StackPtr S, StackData d) /*adds the top element*/
{
NodePtr np = (NodePtr)malloc(sizeof(Node));
np -> data = d;
np -> next = S -> top;
S -> top = np;
}
This is a basic program for implementing stack data structure and its operations. Hope it will help you.
#include<stdio.h>
#include<stdlib.h>
#define INT_MIN -99;
struct Stack{
int data;
struct Stack *next;
};
struct Stack *CreateStack(){
return NULL;
}
void Push(struct Stack **top,int data){
struct Stack *temp;
temp=malloc(sizeof(struct Stack));
if(!temp)
return NULL;
temp->data = data;
temp->next= *top;
*top=temp;
}
int IsEmptyStack(struct Stack *top){
return top==NULL;
}
int Pop(struct Stack **top){
int data;
struct Stack *temp;
if(IsEmptyStack(*top))
return INT_MIN;
temp=*top;
*top=temp->next;
data=temp->data;
printf("%d",data);
free(temp);
return data;
}
int Top(struct Stack *top){
if(IsEmptyStack(top))
return INT_MIN;
return top->next->data;
}
void DeleteStack(struct Stack **top)
{
struct Stack *temp,*p;
p=*top;
while(p->next){
temp=p->next;
p->next=temp->next;
free(temp);
}
free(p);
}
void main(){
struct Stack *s=CreateStack();
Push(&s,5);
Push(&s,15);
Push(&s,52);
Pop(&s);
Pop(&s);
Push(&s,35);
Push(&s,53);
Pop(&s);
Push(&s,45);
}

Segfault in my Linked List implementation

Here's my code:
#include <stdio.h>
typedef struct node_struct {
int data;
struct node_struct *next;
} node;
void push(node *top, int data) {
node *new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->next = top;
top = new_node;
}
int main() {
node *top = (node*) malloc(sizeof(node));
top->data = 1;
printf("Set data of top node to: %d\n", top->data);
push(top, 2);
printf("Pushed 2 to top, top->next->data = %d\n", top->next->data);
}
The program segfaults at the 3rd last line (push(top, 2);) and I think on the line top = new_node;
I'm just learning C (pointers right now).
What did I do wrong?
The problem here is that you pass the pointer to the top element by-value, and then you try to set the pointer inside the function but there it's just a local variable and changes to it will not be visible outside of the function.
Pass the top pointer by reference instead, by using a pointer to the pointer:
void push(node **top, int data) {
node *new_node = malloc(sizeof(node));
new_node->data = data;
new_node->next = *top;
*top = new_node;
}
...
push(&top, 2);
An alternative is to return the new top from the function instead:
node *push(node *top, int data) {
node *new_node = malloc(sizeof(node));
new_node->data = data;
new_node->next = top;
return new_node;
}
...
top = push(top, 2);
Pointer is passed by value to push. Hence, the change you did to top is not reflected in main. If you want to change top then pass the address of pointer:
#include <stdio.h>
typedef struct node_struct {
int data;
struct node_struct *next;
} node;
void push(node **top, int data) {
node *new_node = (node*) malloc(sizeof(node));
new_node->data = data;
new_node->next = *top;
*top = new_node;
}
int main() {
node *top = (node*) malloc(sizeof(node));
top->data = 1;
printf("Set data of top node to: %d\n", top->data);
push(&top, 2);
printf("Pushed 2 to top, top->next->data = %d\n", top->next->data);
}
Here's the relevant C-FAQ.

Resources