Initialize a stack in C by setting pointer to NULL - c

I'm trying to implement stack in C according to the following header (stack.h):
#ifndef STACK_H
#define STACK_H
/* An element from which stack is consisting */
typedef struct stack_node_ss {
struct stack_node_ss *next; /* pointer to next element in stack */
void *value; /* value of this element */
} stack_node_s;
/* typedef so that stack user doesn't have to worry about the actual type of
* parameter stack when using this stack implementation.
*/
typedef stack_node_s* stack_s;
/* Initializes a stack pointed by parameter stack. User calls this after he
* has created a stack_t variable but before he uses the stack.
*/
void stack_init(stack_s *stack);
/* Pushes item to a stack pointed by parameter stack. Returns 0 if succesful,
* -1 otherwise.
*/
int stack_push(void *p, stack_s *stack);
/* Pops item from a stack pointed by parameter stack. Returns pointer to
* element removed from stack if succesful, null if there is an error or
* the stack is empty.
*/
void *stack_pop(stack_s *stack);
#endif
However, being new with C, I'm stuck at the stack_init function, I have written in stack.c:
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"
void stack_init(stack_s *stack) {
(*stack)->value = NULL;
(*stack)->next = NULL;
}
The main program begins with:
int *tmp;
stack_s stack;
stack_init(&stack);
And this crashes my program with:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100000abf in stack_init (stack=0x7fff5fbffb30) at stack.c:6
6 (*stack)->value = NULL;
Can you hint me to the right track? Many thanks.

You have to allocate memory for **stack itself:
*stack = malloc(sizeof(**stack));
But please don't typedef pointer types. That's really confusing and hard to read. Better to pass the pointer by value and leave it to the caller to store the pointer, like this:
typedef struct stack_node_t
{
struct stack_node_t * next;
/* ... */
} stack_node;
stack_node * create_stack()
{
stack_node * res = calloc(1, sizeof(stack_node));
return res;
}
void destroy_stack(stack_node * s)
{
if (!next) return;
stack_node * next = s->next;
free(s);
destroy_stack(next);
}
// etc.
Then you can just say:
stack_node * s = create_stack();
// use s
destroy_stack(s);
s = NULL; // some people like this

You are dereferencing an uninitialised pointer, causing undefined behaviour.
Because this function is creating a new stack, you need to allocate some dynamic memory for the stack and then set the pointer to point to that newly allocated memory:
void stack_init(stack_s *stack) {
*stack = malloc(sizeof(**stack)); // create memory for the stack
(*stack)->value = NULL;
(*stack)->next = NULL;
}
stack_s stack;
stack_init(&stack);
Then you should have a function called stack_destroy that will free the dynamic memory and set the pointer to NULL:
void stack_destroy(stack_s *stack) {
free(*stack);
*stack = NULL;
}

You should initialize the stack to NULL - not to push a NULL value to it:
void stack_init(stack_s *stack) {
*stack=NULL;
}

Related

Assign an address to a function parameter that is a pointer [duplicate]

first time posting here, any help would be appreciated. I'm trying to change the value "size" inside my stack called "try", by putting it through my function called Stack_Init. If I print out the value of "stack->size" inside the function, it gives me the correct value for size (being 4). If I were to print
try->size after executing my function (at the end of the code), it would give me a value of 0.
struct intnode {
int data;
struct intnode *next;
}; typedef struct intnode node;
struct stack {
node *top;
int size;
}; typedef struct stack Stack;
void Stack_Init(Stack *S, int size){
Stack *stack = malloc(size*sizeof(node));
stack->top = NULL;
stack->size = size;//for some reason, this doesn't change try->size
}
int main(){
Stack *try;
int size = 4;
Stack_Init(try,size);
printf("%d %d ", try->size, try->top);
Thanks for reading!
You are trying to change a pointer that you pass to the function, so you need an extra level of indirection, i.e. a pointer to pointer. In addition, you need to assign to dereferenced parameter instead of a local variable:
void Stack_Init(Stack **S, int size){
// ^
// |
// Extra asterisk here
*S = malloc(size*sizeof(node));
// ^
// |
// Dereference the pointer passed into the function
(*S)->top = NULL;
(*S)->size = size;
}
The call to the function needs to look like this:
Stack_Init(&try,size);
// ^
// |
// Pass a pointer to a pointer
Your Stack_Init function has a couple problems with it. You are modifying a local variable instead of the argument passed to the function, and you're assigning the memory incorrectly. Try this instead.
void Stack_Init(Stack **S,int size) {
Stack *stack = (Stack*)malloc(sizeof(Stack));
stack->top = NULL;
stack->size = size;
*S = stack;
}

How to change the value of data inside a struct through a function?

first time posting here, any help would be appreciated. I'm trying to change the value "size" inside my stack called "try", by putting it through my function called Stack_Init. If I print out the value of "stack->size" inside the function, it gives me the correct value for size (being 4). If I were to print
try->size after executing my function (at the end of the code), it would give me a value of 0.
struct intnode {
int data;
struct intnode *next;
}; typedef struct intnode node;
struct stack {
node *top;
int size;
}; typedef struct stack Stack;
void Stack_Init(Stack *S, int size){
Stack *stack = malloc(size*sizeof(node));
stack->top = NULL;
stack->size = size;//for some reason, this doesn't change try->size
}
int main(){
Stack *try;
int size = 4;
Stack_Init(try,size);
printf("%d %d ", try->size, try->top);
Thanks for reading!
You are trying to change a pointer that you pass to the function, so you need an extra level of indirection, i.e. a pointer to pointer. In addition, you need to assign to dereferenced parameter instead of a local variable:
void Stack_Init(Stack **S, int size){
// ^
// |
// Extra asterisk here
*S = malloc(size*sizeof(node));
// ^
// |
// Dereference the pointer passed into the function
(*S)->top = NULL;
(*S)->size = size;
}
The call to the function needs to look like this:
Stack_Init(&try,size);
// ^
// |
// Pass a pointer to a pointer
Your Stack_Init function has a couple problems with it. You are modifying a local variable instead of the argument passed to the function, and you're assigning the memory incorrectly. Try this instead.
void Stack_Init(Stack **S,int size) {
Stack *stack = (Stack*)malloc(sizeof(Stack));
stack->top = NULL;
stack->size = size;
*S = stack;
}

Why do I need to use & to pass a pointer to a struct in this stack implementation [duplicate]

This question already has answers here:
What is the reason for using a double pointer when adding a node in a linked list?
(15 answers)
Closed 7 years ago.
In the following program I need to pass an argument to a function using the &-operator although I expect it to be a pointer and the function is expecting a pointer. Why do I need to do this?
The program implements a simple stack using linked lists and incomplete types in C. Here are the three necessary files:
stack.h
#ifndef STACK_H
#define STACK_H
#include <stdbool.h>
struct Stack {
int number;
struct Stack *next;
};
/*
* We declare a pointer to a Stack structure thereby making use of incomplete
* types. Clients that pull in stack.h will be able to declare variables of type
* pstack which are pointers to Stack structures. */
typedef struct Stack *pstack;
bool is_empty(pstack *s);
void make_empty(pstack *s);
void push(pstack *s, int new_num);
int pop(pstack *s);
#endif /* STACK_H */
stack.c
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
bool is_empty(pstack *s)
{
return !s;
}
void make_empty(pstack *s)
{
if (!is_empty(s))
pop(s);
}
int pop(pstack *s)
{
struct Stack *tmp;
int i;
if (is_empty(s)) {
exit(EXIT_FAILURE);
}
tmp = *s;
i = (*s)->number;
*s = (*s)->next;
free(tmp);
return i;
}
void push(pstack *s, int new_num)
{
struct Stack *new_node = malloc(sizeof(struct Stack));
if (!new_node) {
exit(EXIT_FAILURE);
}
new_node->number = new_num;
new_node->next = *s;
*s = new_node;
}
stackclient.c
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
int main(void)
{
pstack s1;
int n;
push(&s1, 1);
push(&s1, 2);
n = pop(&s1);
printf("Popped %d from s1\n", n);
n = pop(&s1);
printf("Popped %d from s1\n", n);
exit(EXIT_SUCCESS);
}
Again, I thought that by using
typedef struct Stack *pstack;
and later on in main()
pstack s1;
I'm declaring a pointer to the linked list Stack and hence it would be fine to simply pass s1 to say push() by just using
push(s1, 1);
but I actually need to use
push (&s1, 1);
Why?
Your functions are all declared to take pstack* as an argument, which is actually a pointer to a pointer to a Stack struct. Just use pstack. You'll also need to replace the instances of (*s) with just s in the implementations of those functions.
Edit: As was pointed out in the comments, you actually write to (*s) in the function implementations and rely on this behavior for correctness, so you need to keep the argument as pstack*. Conceptually, this is because the stack variable (s1) is literally the top of the stack itself, and so must be modified by push and pop.
You need to use pstack *s ( pointer to pstack ) in void push(pstack *s, int new_num), according to your implementation code,
if to use pstack s( pstack ), the new_node will not be returned correctly.
Two possible ways to insert a Node in push():
if insert to head, it should be *s = new_node
if insert to tail, it could be s->next = new_node
Back to the code, if to use push(s1, 1); such as,
//If only use pstack s, the new_node can not be pushed.
void push(pstack s, int new_num) //it is a wrong implementation for demo
{
struct Stack *new_node = malloc(sizeof(struct Stack));
if (!new_node) {
exit(EXIT_FAILURE);
}
new_node->number = new_num;
new_node->next = s;
s = new_node;// WRONG! here, the new_node cannot be kept by s
// two typical node insert ways:
// 1)if insert to head, it should be *s = new_node
// 2)if insert to tail, it could be s->next = new_node
//Now, Your code applied the #1 way, so need *s
}
So, it should be inputed pstack *s, and call with push (&s1, 1);
void push(pstack *s, int new_num)//it is the correct version the same as your post
{
struct Stack *new_node = malloc(sizeof(struct Stack));
if (!new_node) {
exit(EXIT_FAILURE);
}
new_node->number = new_num;
new_node->next = *s;
*s = new_node;//here, the new_node could be kept by *s
}

C Programming Stack

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.

Creating a stack of strings in C

I want to have a stack that takes strings. I want to be able to push and pop strings off, as well as clear the whole stack. I think C++ has some methods for this. What about C?
Quick-and-dirty untested example. Uses a singly-linked list structure; elements are pushed onto and popped from the head of the list.
#include <stdlib.h>
#include <string.h>
/**
* Type for individual stack entry
*/
struct stack_entry {
char *data;
struct stack_entry *next;
}
/**
* Type for stack instance
*/
struct stack_t
{
struct stack_entry *head;
size_t stackSize; // not strictly necessary, but
// useful for logging
}
/**
* Create a new stack instance
*/
struct stack_t *newStack(void)
{
struct stack_t *stack = malloc(sizeof *stack);
if (stack)
{
stack->head = NULL;
stack->stackSize = 0;
}
return stack;
}
/**
* Make a copy of the string to be stored (assumes
* strdup() or similar functionality is not
* available
*/
char *copyString(char *str)
{
char *tmp = malloc(strlen(str) + 1);
if (tmp)
strcpy(tmp, str);
return tmp;
}
/**
* Push a value onto the stack
*/
void push(struct stack_t *theStack, char *value)
{
struct stack_entry *entry = malloc(sizeof *entry);
if (entry)
{
entry->data = copyString(value);
entry->next = theStack->head;
theStack->head = entry;
theStack->stackSize++;
}
else
{
// handle error here
}
}
/**
* Get the value at the top of the stack
*/
char *top(struct stack_t *theStack)
{
if (theStack && theStack->head)
return theStack->head->data;
else
return NULL;
}
/**
* Pop the top element from the stack; this deletes both
* the stack entry and the string it points to
*/
void pop(struct stack_t *theStack)
{
if (theStack->head != NULL)
{
struct stack_entry *tmp = theStack->head;
theStack->head = theStack->head->next;
free(tmp->data);
free(tmp);
theStack->stackSize--;
}
}
/**
* Clear all elements from the stack
*/
void clear (struct stack_t *theStack)
{
while (theStack->head != NULL)
pop(theStack);
}
/**
* Destroy a stack instance
*/
void destroyStack(struct stack_t **theStack)
{
clear(*theStack);
free(*theStack);
*theStack = NULL;
}
Edit
It would help to have an example of how to use it:
int main(void)
{
struct stack_t *theStack = newStack();
char *data;
push(theStack, "foo");
push(theStack, "bar");
...
data = top(theStack);
pop(theStack);
...
clear(theStack);
destroyStack(&theStack);
...
}
You can declare stacks as auto variables, rather than using newStack() and destroyStack(), you just need to make sure they're initialzed properly, as in
int main(void)
{
struct stack_t myStack = {NULL, 0};
push (&myStack, "this is a test");
push (&myStack, "this is another test");
...
clear(&myStack);
}
I'm just in the habit of creating pseudo constructors/destructors for everything.
Try GNU Obstacks.
From Wikipedia:
In the C programming language, Obstack is a memory-management GNU extension to the C standard library. An "obstack" is a "stack" of "objects" (data items) which is dynamically managed.
Code example from Wikipedia:
char *x;
void *(*funcp)();
x = (char *) obstack_alloc(obptr, size); /* Use the macro. */
x = (char *) (obstack_alloc) (obptr, size); /* Call the function. */
funcp = obstack_alloc; /* Take the address of the function. */
IMO what makes Obstacks special: It does not need malloc() nor free(), but the memory still can be allocated «dynamically». It is like alloca() on steroids. It is also available on many platforms, since it is a part of the GNU C Library. Especially on embedded systems it might make more sense to use Obstacks instead of malloc().
See Wikipedia's article about stacks.

Resources