C Programming Stack - c

I am currently working on stacks right now. I am supposed to use the following structures and function prototypes:
typedef struct node_{
char data;
struct node_ *next;
}node;
typedef struct stack_{
unsigned int size;
node* stack;
}stack;
stack* create_stack();
void push(stack* s, char val);
Here is my actual code for create_stack() and push():
stack* create_stack()
{
stack *stack;
stack = malloc(sizeof(stack));
stack->size = 0;
stack->stack = NULL;
return stack;
}
void push(stack* s, char val)
{
stack *newStack;
newStack = create_stack();
newStack->stack->data = val;
newStack->stack = s->stack;
s = newStack;
}
I am getting a segmentation fault when I try to store char val into newStack->stack->data. How does this not work? What do I need to do to make this stack on top???

The push function is wrong.
void push(stack* s, char val)
{
stack *newStack;
newStack = create_stack(); /* new stack created, why not work on the existing one ? */
newStack->stack->data = val; /* you're writing to a NULL pointer */
newStack->stack = s->stack;
s = newStack; /* this will not be visible from outside the function */
}
First of all, you are trying to recreate a new stack for each call of this function, which is certainly not what is intended.
If you try to modify the value of s, it will not be visible from outside the function, and you will still have your original stack.
Then, you are accessing the stack->data member even though stack has no space allocated to it yet (because you set it to NULL). You actually set it right after, which is why it crashes, most probably.
You probably want to do something like this:
void push(stack* s, char val)
{
node * n;
/* go to the end of the "stack" */
n = s->stack;
while (n != NULL) {
n = n->next;
}
/* allocate memory for a new node */
n = malloc(sizeof(node));
/* initialize node */
n->data = val;
n->next = NULL;
/* increment stack size */
s->size++;
}
And as mentionned before, this is merely a singly-linked list which is not the best fit for a stack, because as it exists now, you have to follow the node pointers to reach the last element, which makes push and pop operations O(N).
A faster implementation would look like this:
void push(stack* s, char val)
{
node * first_node, * new_node;
first_node = s->stack;
/* allocate memory for a new node */
new_node = malloc(sizeof(node));
/* initialize node */
new_node->data = val;
new_node->next = first_node;
/* increment stack size */
s->stack = new_node;
s->size++;
}
The top of the stack is always the first node, and the performance is O(1).

Follow your code....
stack *newStack = create_stack(); // in push()
newStack = malloc(sizeof(stack)); // in create_stack()
newStack->stack = NULL; // in create_stack()
newStack->stack->data = val; // in push()... this is where you crash.

Because newStack->stack is a NULL pointer. Your create_stack() function sets it to NULL, and you then dereference it. You have to allocate a struct node somewhere.
This code also has some readability issues which might be contributing to the problem. You are naming variables the same names as their types, which is very confusing. Consider using some other naming pattern like stack_t for types and stack for variable names.

Related

Stack using linked list in C, freeing temp_node in pop function but still want to return it

I am implementing a stack using linked list in C, and I stumbled upon two issues:
I need the stack_pop function to return a valid value temp, that is the temporary node/cell, and therefore, I can't free it. So, 1) Do you think freeing each node for every pop function call is better than until the end using the stack_destroy() 2) How can I achieve both, free(temp) and return it at the same time in stack_pop?
How bad my implementation becomes not using exit(1) in both stack_push and stack_pop functions?
This is the implementation:
//// Stack
// Linked list
typedef struct {
int data;
Cell* next;
} Cell;
struct stack_l {
size_t count;
Cell *top;
};
typedef struct stack_l *Stack;
You've got stack_pop declared to return an int, but you're attempting to return a Cell * which doesn't make sense.
Copy the value in the popped cell to a local variable, free the popped cell, then return the value.
temp = stack->top;
stack->top = stack->top->next;
temp->next = NULL;
stack->count--;
int val = temp.data;
free(temp)
return val;
Also, it makes no sense to call exit in either stack_push or stack_pop as that ends the program.
I think it is a bit overcomplicated. You only need to remember the previous stack pointer. Nothing else
typedef struct stack
{
int data;
struct stack *prev;
}stack;
stack *push(stack **sp, int data)
{
stack *new = malloc(sizeof(*new));
if(new)
{
new -> prev = *sp;
new -> data = data;
*sp = new;
}
return new;
}
int isempty(stack *sp)
{
return !stack_pointer;
}
int pop(stack **sp)
{
stack *new;
int result = 0;
if(sp && *sp)
{
result = (*sp) -> data;
new = (*sp) -> prev;
free(*sp);
*sp = new;
}
return result;
}
int main(void)
{
stack *stack_pointer = NULL;
int result;
push(&stack_pointer, 1);
push(&stack_pointer, 2);
push(&stack_pointer, 3);
do
{
result = pop(&stack_pointer);
printf("%d\n", result);
}while(stack_pointer) ;
printf("Stack was empty so the loop has exited\n");
}

How to implement a character string in a linked list

The main code itself works fine but I want to make use of character strings instead of the char, and it might be because I've overlooked something absurdly simple. Here is a small snippet of code:
struct Stack
{
char *SData;
int counter;
struct Stack *next;
};
struct Stack* StackNewNode(char SData)
{
struct Stack *stackNode = (struct Stack*)malloc(sizeof(struct Stack));
stackNode->SData = SData; //error here because of the difference of char, should i use []?
stackNode->next = NULL;
return stackNode;
}
void PUSH(struct Stack **root, char SData) //this part only pushes a character
{
struct Stack *stackNode = StackNewNode(SData);
stackNode->next = *root;
*root = stackNode;
printf("\n%c pushed to stack\n", SData);
}
void POP(struct Stack **root)
{
if (*root == NULL)
{
return;
}
struct Stack *temp = *root;
*root = (*root)->next;
char pop = temp->SData; //how should i pop a full string?
free(temp);
printf("%c popped from stack\n", pop);
}
I also want to implement a counter in the Stack. Should i use Stack->counter++ or is there some other more correct way to do it?
Sorry for the wall of text its my first time here
I don't see counter in struct Stack used anywhere in the code snippets you provided. Assuming you want some count of the number of elements in the stack, it wouldn't make sense for this value to be part of the struct. After all, you only need one count, not one attached to every element in the stack. You would want to make this its own variable, perhaps a global defined in the same place as you define root. Just make sure to initialize it to zero.
As for using character strings, you already have char *SData, which can point to a string. All you need to do is change PUSH and StackNewNode to use char* parameter rather than char and then pass it a string, something like this:
PUSH(&root, "My string");
To start with your current code have some type mismatch here: stackNode->SData = SData;
stackNode->SData is a char pointer and SData is a char. I assume your compiler warns you about that - never ignore warnings.
If you want to use C type string you need updates like:
Pass char pointer instead of char
Allocate memory for the string
Copy the passed string to the allocated memory
Free the memory when done
Something like:
struct Stack
{
char *SData;
int counter;
struct Stack *next;
};
struct Stack* StackNewNode(const char* str)
{
struct Stack *stackNode = malloc(sizeof(struct Stack));
if (stackNode == NULL) exit(1);
stackNode->SData = malloc(strlen(str) + 1);
if (stackNode->SData == NULL) exit(1);
strcpy(stackNode->SData, str);
stackNode->next = NULL;
return stackNode;
}
void PUSH(struct Stack **root, const char* str)
{
struct Stack *stackNode = StackNewNode(str);
stackNode->next = *root;
*root = stackNode;
printf("\n%s pushed to stack\n", str);
}
void POP(struct Stack **root)
{
if (*root == NULL)
{
return;
}
struct Stack *temp = *root;
*root = (*root)->next;
printf("%s popped from stack\n", temp->SData);
free(temp->SData);
free(temp);
}
Usage example:
struct Stack *root = NULL;
PUSH(&root, "Hello World");
Adding a counter
In your code you have placed int counter; inside every stack element. You can make that work but I would prefer two structs. One struct type holding information about the whole stack and another struct type for the elements.
Like:
struct StackNode
{
char *SData;
struct StackNode *next;
};
struct Stack
{
int counter;
struct StackNode *root;
};
The functions would need some updates like:
void PUSH(struct Stack *stack, const char* str)
{
struct StackNode *stackNode = StackNewNode(str);
stackNode->next = stack->root;
stack->root = stackNode;
++stack->counter; // Increment counter
printf("\n%s pushed to stack\n", str);
}
Usage example:
struct Stack stack = {0, NULL};
PUSH(&stack, "Hello World");

Stack in C, how to

struct stack
{
int value;
struct stos *w;
};
struct stack *pnt;
struct stack *prev;
void push(value);
void delete(struct stack *new);
void print_stack();
void push(int x)
{
prev = pnt;
pnt = (struct stack*)malloc(sizeof(struct stack));
pnt->value=x;
pnt->w = prev;
printf("Top of stack: %d\n", pnt->value);
}
void delete(struct stack *new)
{
if (new!=NULL)
{
prev = new->w;
printf("Deleted: %d\n", new->value);
free(new);
pnt = prev;
}
else printf("Stack is empty\n");
}
void print_stack()
{
printf("Content of stack:\n");
prev = pnt;
while (prev!=NULL)
{
printf("%d\n", prev->value);
prev = prev->w;
}
}
I have a question about the pointers there. Not what every pointer means (probably means top of stack) but what is meant by 'prev' and 'pnt'.
I just don't get it at all. 'Prev' maybe is a previous value of stack?
Maybe somebody can show me a picture.
pnt is a pointer, as declared by,
struct stack *pnt;
struct stack *prev;
it points to a stack struck declared by
struct stack
{
int value;
struct stos *w; // struct stos should struct stack
};
You are missing this declaration from the other code.
typedef struct stos{
int value;
struct stos *next;
} stos;
So, this is lifted code that has problems, a lot of problems...
Let us begin
First fix the stos mess:
The problems the two structs above were lifted (copied/pasted) so instead of the struct stack containing a pointer to same type of structure is looking for an undefined structure struct stos *next; it should be struct stack* next;
typedef struct Stack;
typedef struct stack {
int value;
Stack* next;
} Stack;
struct stack *pnt; // pnt = pointer top of stack
struct stack *prev; // prev = pointer to the previous stack item
So now we know the stack is kept as a singularly linked list of stack structs.
Let's decipher void push(int x)
void push(int x)
{
// point prev to pnt, previous to top of stack
prev = pnt;
// create a new item to place on the top of the stack
pnt = (struct stack*)malloc(sizeof(struct stack));
// initial the value member of the new item with x
pnt->value=x;
// point the new item's link point to point the previous top of the stack
pnt->w = prev;
// print the value contained in the new top of the stack item.
printf("Top of stack: %d\n", pnt->value);
}
This function is a disaster because it use the keyword new as the name of a variable. Yes, new is in C++. But why make a mess of things for the next person.
void delete(struct stos *new)
{
if (new!=NULL)
{
prev = new->w;
printf("Deleted: %d\n", new->value);
free(new);
pnt = prev;
}
else printf("Stack is empty\n");
}
Should have been written as follows...
// forward declaration of Stos because it won't be defined until the end of struct it is used in.
typedef struct {
int value;
struct Stack* next;
} Stack;
Stack* pnt; // pnt = pointer top of stack
Stack* prev; // prev = pointer to the previous stack item
Using Stack* pnt versus Stack *pnt says, "A Stack pointer called pnt" versus "A pointer called pnt which points to Stacks". (There is also a spiral trick to read these declarations easier Q.E.D)
void delete( Stack* pNew)
{
if ( pNew )
{
prev = pNew->w;
printf("Deleted: %d\n", pNew->value);
free(pNew);
pnt = prev;
}
else printf("Stack is empty\n");
}
As I said, this is a mess.
What is important is you asked a question and hopefully have learned a few things that will help you on your next piece of code.
once you create a typedef, then use it. drop the struct stack stuff
make the names of variables long enough so that future readers will understand the code Stack* pTopOfStack;
try not to use words that are keywords in derivatives new
Don't over crowd the code with redundant code
if ( new != NULL ) versus if ( new ), even better if ( pNewStackItem )
Better to fully understand what the code is doing instead of complicating it with more stuff that looks right, compiles and runs. Never trust a programmer, "sorry, it works on my machine."

Destructor and constructor in C

I'm very new to C and I'm trying yet to fully understand it. I implemented a stack
but found trouble when making its destructor and it constructor/init.
Are these well done?
These are the typedefs for the structures used by the stack:
typedef struct Node{
void* cargo;
struct Node* next;
}Node;
typedef struct Stack{
int size;
Node* firstOut;
}Stack;
And these are the functions:
void newStack(Stack* stack){
stack = (Stack*)malloc(sizeof(Stack));
stack->firstOut = NULL;
stack->size = 0;
}
void freeStack(Stack** stack){
empty((*stack));
free((*stack)->top);
(*stack)->size = 0;
free(stack);
}
My question is: are they well done? How would someone with proper experience do it?
newStack should simply return the stack pointer that it allocates. It doesn't need to receive a Stack* as an argument.
stack *newStack() {
Stack *stack = malloc(sizeof(Stack));
if (stack != NULL) { // allocation successful
stack->firstOut = NULL;
stack->size = 0;
}
return stack;
}
and freeStack should receive a stack pointer as argument, it doesn't need double indirection.
void freeStack(Stack *stack) {
empty(stack);
free(stack->firstOut); // This isn't done by empty()?
free(stack);
}
There's no need to set stack->size before freeing, since the memory is going to go away and the value it contains is irrelevant.

Implementing a linked list with a stack in C

For a prelab (meaning it's not for a grade), I'm supposed to implement my first ever stack using linked lists. I wrote it adding only one thing to the stack just as practice, as to why it's so short. Anyway, I have no compile errors, besides it saying that "new" is uninitialized in my create_stack function. This is also where I'm getting a segmentation fault, as it's not printing out my first printf function. I am also guessing that the problem is bigger than just me initializing the stack, but this is my problem's start. Please go easy on me if it's something simple, as, like I said, it's my first time doing stacks, and thanks for your help.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_{
char data;
struct node_ *next;
}node;
typedef struct stack_{
unsigned int size;
node* stack;
}stack;
stack* create_stack();
void push(stack* s, char val);
char top(stack* s);
void pop(stack*s);
int main(void) {
char value, val;
stack* new = create_stack();
printf("Enter a letter: ");
scanf("%c", &value);
push(new, value);
val = top(new);
printf("%c\n", val);
pop(new);
return 0;
}
stack* create_stack(){ //initializes the stack
stack* new;
new->size = 0;
new->stack = NULL;
return new;
}
void push(stack* s, char val) {
node* temp = (node*)malloc(sizeof(node)); //allocates
if ( temp == NULL ) {
printf("Unable to allocate memory\n");
}
else{
temp->next = s->stack;
temp->data = val;
s->stack = temp;
s->size = (s->size) + 1; //bumps the counter for how many elements are in the stack
}
}
void pop(stack* s) {
node* temp;
temp = s->stack;
s->stack = temp->next;
free(temp);
s->size = (s->size) - 1; //subtracts from counter
}
char top(stack* s) {
node* temp = s->stack;
char value = temp->data;
return value;
}
The reason it crashes is that you never allocate any memory when you create the stack. Do stack* new = malloc (sizeof(stack)); in the create_stack function.
For the future you might want to use better variable names. Using for instance using new as the name for the stack isn't that good - it isn't very descriptive plus it's a reserved keyword in several languages, C++ for example.
stack *new creates a local pointer, but it has nothing to point to yet. Since you want the stack to continue to exist after the function completes, you should allocate memory for it using malloc (and eventually free it using free).
So your create_stack function should start with:
stack* new = malloc(sizeof(stack));
An alternative would be to declare the stack as a local variable in your main function, and pass it as an argument into create_stack to initialize it:
stack new;
create_stack(&new);

Resources