Error in creating stack header file. In C - 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.

Related

Why I need to cast "((node)s->top)->next = q" on "push" method? Dubs an declaration pointer to struct

I'd like to have explanations regard some dubs. Here is the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct sNode {
int data;
struct sNode* next;
} sNode;
typedef sNode* node;
typedef struct {
node *top;
node *head;
int nodes;
} stack;
void push(stack *s);
void printStack(stack *s);
int main(){
srand((unsigned)time(NULL));
stack s = {NULL, NULL, 0};
push(&s);
push(&s);
push(&s);
push(&s);
printStack(&s);
return 0;
}
void push(stack *s){
node q = (node)malloc(sizeof(sNode));
q->data = rand() % 10 + 1;
q->next = NULL;
if(s->top){
((node)s->top)->next = q;
s->top = q;
} else {
s->top = q;
}
if(s->nodes == 0) s->head = q;
s->nodes++;
}
void pop(stack *s){
}
void printStack(stack *s){
printf("Number of nodes: %d\n", s->nodes);
node q = s->head;
while(q != NULL){
printf("%d -> ", q->data);
q = q->next;
}
printf("NULL");
}
Can you explain me why I need to cast (*node) on function push? Why, also, is sufficient declare a pointer to the struct in this way:
stack *s;
and start working on?
What's the difference with this:
stack s;
stack *ss = &s;

Can't push after using pop

I've been at this for about 7 hours trying to get this to work on my own, but I can't figure it out. With my testing earlier I was able to successfully fully push all the values of my char[] into the stack and I could properly pop them off and return the value.
However, if I try to push something back onto the stack then the whole program crashes.
Notes:
The code is supposed to be used to create nodes for an Expression Tree later on
The commented out code in the switch statement is code that I had when the error occurred, was just saving it for when I could have fixed it.
-When pushing after using a pop, the function is properly called, however it does not enter either the if or the else statement within push.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Stack;
typedef struct StackNode;
typedef struct StackPtr;
struct StackPtr
{
struct StackPtr *prev;
struct StackNode *ptr;
};
struct StackNode
{
char c;
struct StackNode *lchild;
struct StackNode *rchild;
};
struct Stack
{
struct StackPtr *top;
};
// Prototypes
void initStack(struct Stack*);
struct StackNode* createNode(char);
struct StackNode* pop(struct Stack*);
void push(struct Stack*, struct StackNode*);
int isEmpty(struct Stack*);
int main()
{
struct Stack *s = malloc(sizeof(s));
initStack(s);
char exp[7] = "45+67+*";
int length = 0;
for(length; length<3; length++) // push the expression onto the stack
{
struct StackNode *exp1 = malloc(sizeof(exp1));
struct StackNode *exp2 = malloc(sizeof(exp2));
struct StackNode *c = malloc(sizeof(c));
if(exp[length] > 47 && exp[length] < 58) // is a number
{
c->c = exp[length];
push(s,c);
}
else
{
switch(exp[length])
{
default:
printf("exp[length] error\n");
break;
case '+':
exp2 = pop(s);
exp1 = pop(s);
c->c = '7';
push(s, c);
//push(s, exp1->ptr);
//push(s, exp2->ptr);
//c->c = exp[length];
//c->rchild = exp2;
//c->lchild = exp1;
//printf("test ");
//push(s, c);
//printf("test ");
break;
case '-':
break;
case '*':
break;
case '/':
break;
}
}
}
return 0;
}
void initStack(struct Stack *s)
{
struct StackNode *n = malloc(sizeof(n));
struct StackPtr *p = malloc(sizeof(p));
n->c = NULL;
n->lchild = NULL;
n->rchild = NULL;
p->prev = NULL;
p->ptr = n;
s->top = p;
}
struct StackNode* createNode(char c)
{
struct StackNode *n = malloc(sizeof(n));
n->c = c;
n->lchild = NULL;
n->rchild = NULL;
return n;
}
void push(struct Stack *s, struct StackNode *n)
{
if(s->top->ptr->c == NULL) // First item being pushed
{
s->top->ptr = n;
printf("1Added: %c to the stack\n", n->c);
}
else
{
struct StackPtr *o = malloc(sizeof(o));
o->prev = s->top;
s->top = o;
s->top->ptr = n;
printf("2Added: %c to the stack\n", n->c);
}
}
struct StackNode* pop(struct Stack *s)
{
if(isEmpty(s) == 1)
{
printf("Stack is empty!\n");
return;
}
else
{
struct StackPtr *tmp = malloc(sizeof(tmp));
tmp = s->top;
s->top = s->top->prev;
printf("Popped: %c from the stack.\n",tmp->ptr->c);
return tmp->ptr;
}
}
int isEmpty(struct Stack *s)
{
if(s->top == NULL)
return 1;
else
return 0; // false
your POP function is setting
s->top = s->top->prev;
after two nodes are popped out the Prev value is NULL so top is pointing to NULL, which is causing the segmentation fault during the next PUSH
Few more things to consider, change value to 8 instead of 7 as \0 needs to be fit. or use it as
char exp[]
char exp[8] = "45+67+*";

Segmentation fault while getting the size of Linked list

I am getting segmenation fault when calling the function getLength. I edited the code,
now I am getting length as 0 instead of 5.
#include <stdio.h>
#include <stdlib.h>
node *headptr;
node *topptr;
typedef struct node
{
int value;
struct node *nextPtr;
}node;
void initializeLinkedList(node *headptr, node *topptr)
{
int i=0;
headptr = (node*)malloc(sizeof(node));
topptr = (node*)malloc(sizeof(node));
topptr = headptr;
headptr->value=i;
headptr->nextPtr = (node*)malloc(sizeof(node));
for(i=1;i<5;i++)
{
headptr = headptr->nextPtr ;
headptr->value=i;
headptr->nextPtr=(node*)malloc(sizeof(node));
printf("val is %p \n ", *headptr);
}
headptr->nextPtr = NULL;
}
int getLength(node *topptr)
{
int i=0;
node* local;
local = topptr;
while(local!=NULL)
{
local=local->nextPtr;
i++;
}
return i;
}
int main()
{
initializeLinkedList(headptr,topptr);
printf("val is %d \n", getLength(topptr));
return 0;
}
void initializeLinkedList(node *headptr, node *topptr)
change it to
void initializeLinkedList(node *headptr, node** topptr)
and change your code accordingly...
There are lot of other issues too...
When you need a pointer just define the pointer don't allocate memory and overwrite the poiter..
If i have to code it
void initializeLinkedList( node **topptr)
{
int i=0;
node* headptr = (node*)malloc(sizeof(node));
headptr->value=i;
*topptr = headptr;
for(i=1;i<5;i++)
{
headptr->nextPtr = (node*)malloc(sizeof(node));
headptr->nextPtr->value=i;
headptr->nextPtr->nextPtr=NULL;
headptr=headptr->nextPtr;
}
}
int main()
{
node* topptr;
initializeLinkedList(&topptr);
printf("val is %d \n", getLength(topptr));
return 0;
}
initializeLinkedList does not modify the variables headptr and topptr defined in main (pass by value). Hence the variable passed to getLength contains junk.
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int value;
struct node *nextPtr;
} node;
void initializeLinkedList(node **top, node **rear){
int i=0;
node *local;
*top = (node*)malloc(sizeof(node));
local = *top;
local->value=i;
local->nextPtr = NULL;
for(i=1;i<5;++i){
local->nextPtr = (node*)malloc(sizeof(node));
local = local->nextPtr;
local->value = i;
local->nextPtr = NULL;
}
*rear = local;
}
int getLength(node *np){
int i;
for(i=0;np!=NULL;++i, np = np->nextPtr)
;//printf("debug:%d\n", np->value);
return i;
}
int main(void){
node *top, *rear;
initializeLinkedList(&top, &rear);
printf("length is %d \n", getLength(top));
return 0;
}

C linked list push function, just checking if this is correct

So I'm just wondering if this push function, which pushes a new value to the top a linked list stack is correct
void push(node** hd, int v){
node temp;
temp = (node*)malloc(sizeof(node));
temp -> val = v;
temp -> next = *hd;
*hd = temp;
}
Thanks in advance!
Also I'm wondering how I would make a pop function, to pop the most recently pushed value off of the stack.
The struct code looks like this by the way...
typedef struct nodeStruct
{
int val;
struct nodeStruct* next;
}node;
typedef node* list;
Dont define pointer types. They are confusing. Define a normal type and dereference it explicitly. Here is what you were trying to do without the pointer types.
#include <stdlib.h>
#include <stdio.h>
typedef struct nodeStruct
{
int val;
struct nodeStruct *next;
} node;
static void push(node **head, int v)
{
node *temp = malloc(sizeof(node));
temp->val = v;
temp->next = *head;
*head = temp;
}
int main(int argc, char **argv)
{
(void) argv;
(void) argc;
node *list = NULL;
for (int i=0; i<10; ++i) {
push(&list, i);
}
for(node *l = list; l != NULL; l = l->next) {
printf("%d ", l->val);
}
printf("\n");
return 0;
}
Note that you should check for failure of malloc. In other words, malloc can return NULL, which should be handled - left to you.

C Typed Stack: Linked-List Implementation

I have a computer science exam coming up and a large portion is going to be on programming in ansi C. I'm new to C and as a review I tried to implement a stack using a linked-list. My code compiles but it doesn't run as expected.
I believe there is an error with my push() function. I'm assuming that my stack reference isn't being updated properly.
I wrote the following code from scratch to study / practice. Any advice on how to fix my code or improve my programming style would be greatly appreciated.
Thanks guys!
stack.h
#ifndef __STACK__
#define __STACK__
#include <stdlib.h>
#include "bool.h"
#define EMPTY -1
typedef struct Node {
int index;
enum { INT = 0, CHAR, STRING } type;
union {
int i;
char c;
char* s;
} value;
struct Node* prev;
} Node;
typedef Node* Stack;
Stack init();
void push(Stack stack, int type, void* value);
void pop(Stack stack, Node* node);
void empty(Stack stack);
Bool isempty(Stack stack);
#endif
stack.c
#include <stdlib.h>
#include <string.h>
#include "stack.h"
Stack init() {
Stack stack = (Node*) malloc(sizeof(Node));
stack->index = EMPTY;
stack->type = INT;
stack->value.i = 0;
stack->prev = 0;
return stack;
}
void push(Stack stack, int type, void* value) {
int length;
Node* node = (Node*) malloc(sizeof(Node));
node->index = stack->index + 1;
node->type = type;
switch(node->type) {
case INT:
node->value.i = *((int*) value);
break;
case CHAR:
node->value.c = *((char*) value);
break;
case STRING:
length = strlen((char*) value) + 1;
node->value.s = (char*) malloc(length * sizeof(char));
strcpy(node->value.s, value);
break;
}
node->prev = stack;
stack = node;
}
void pop(Stack stack, Node* node) {
int length;
Node* temp = stack;
if (!isempty(stack)) {
node->index = stack->index;
node->type = stack->type;
switch(stack->type) {
case INT:
node->value.i = stack->value.i;
break;
case CHAR:
node->value.c = stack->value.c;
break;
case STRING:
length = strlen(stack->value.s) + 1;
node->value.s = (char*) malloc(length * sizeof(char));
strcpy(node->value.s, stack->value.s);
free(stack->value.s);
break;
}
node->prev = 0;
stack = stack->prev;
free(temp);
} else {
/*TODO: handle empty case */
puts("Stack empty!");
}
}
void empty(Stack stack) {
while (!isempty(stack)) {
Node* temp = malloc(sizeof(Node));
pop(stack, temp);
free(temp);
}
}
Bool isempty(Stack stack) {
return stack->index == EMPTY ? TRUE : FALSE;
}
bool.h
#ifndef __BOOL__
#define __BOOL__
typedef int Bool;
#define FALSE 0
#define TRUE 1
#endif
main.c
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"
int main() {
Stack stack = init();
Node* node = malloc(sizeof(Node));
int i = 5;
push(stack, 0, &i);
pop(stack, node);
printf("Node value: %d\n", node->value.i);
free(node);
empty(stack);
puts("done.");
return 0;
}
Really you are not modifying stack. You must to use &stack for push, pop and empty methods. They will have following signature:
void push(Stack * stack, int type, void* value);
void pop(Stack * stack, Node* node);
void empty(Stack *stack);
and, of course, use pointer contents inside these methods, like:
void push(Stack * stack, int type, void* value) {
int length;
Node* node = (Node*) malloc(sizeof(Node));
node->index = (*stack)->index + 1;
node->type = type;
switch(node->type) {
case INT:
node->value.i = *((int*) value);
break;
case CHAR:
node->value.c = *((char*) value);
break;
case STRING:
length = strlen((char*) value) + 1;
node->value.s = (char*) malloc(length * sizeof(char));
strcpy(node->value.s, value);
break;
}
node->prev = *stack;
*stack = node;
}
void pop(Stack * stack, Node* node) {
int length;
Node* temp = *stack;
if (!isempty(*stack)) {
node->index = (*stack)->index;
node->type = (*stack)->type;
switch((*stack)->type) {
case INT:
node->value.i = (*stack)->value.i;
break;
case CHAR:
node->value.c = (*stack)->value.c;
break;
case STRING:
length = strlen((*stack)->value.s) + 1;
node->value.s = (char*) malloc(length * sizeof(char));
strcpy(node->value.s, (*stack)->value.s);
free((*stack)->value.s);
break;
}
node->prev = 0;
*stack = (*stack)->prev;
free(temp);
} else {
/*TODO: handle empty case */
puts("Stack empty!");
}
}
void empty(Stack *stack) {
while (!isempty(*stack)) {
Node* temp = malloc(sizeof(Node));
pop(stack, temp);
free(temp);
}
}

Resources