Beruflich Dokumente
Kultur Dokumente
the Stack
Table of Contents
Introduction
Implementation in C
2.1
Memory management
2.2
Introduction
Let's have a simple representation of what this mean. Here is an empty stack
At this point, the stack is empty and stores no data. Indeed, to have our stack store some
bunch of data, we need to use the elementary action push .
When we push , let's say, 10 , here is what we get
As you can see, we've added a value onto the stack. But what happens if we push 8 ?
Once again we've pushed a value onto the stack. How can we get 10 now ? Well, a stack is
to be understood as a pile of books. When you push a book onto another book, you create a
stack ! And to get any book in the stack, you have to remove every book above it, that is to
say pop every book that is above the one we want to get.
How can we get 10 back ?
To retrieve 10, we have to pop the stack twice. The first pop() will return 8 and the second
one will return 10, which is what we want !
Implementation in C
This section is dedicated to a minimalist implementation of a stack in C .
Implementation in C
1 - Stack struct
I will neither discuss how structs are implemented in C, nor tell you how to use them. But
let's see how we can declare a convenient structure for our stack.
First of, let's create a stack.h header file to store our functions prototypes.
// stack.h
#ifndef _STACK_H_
#define _STACK_H_
#endif /* _STACK_H_ */
This basic header-guard prevents recursive inclusion of the header. Now let's list what we
need to know about our stack.
In the first place, we need to have a variable to keep track of the maximum stack's size.
// stack.h
typedef struct {
int size;
} Stack;
We also need a variable to keep track of the current size of the stack, that is to say how
many elements are stored in the stack. Let us call it sp . (this name stands for stack
pointer, which is a sort of convention).
// stack.h
typedef struct {
int sp;
int size;
} Stack;
2 - Memory management
2.a - Memory allocation
I've already told you that C doesn't support Object-Oriented programming. Thus, we have to
manage ourselves how memory is allocated / freed for our structs. Of course, you remember
our Stack is implemented as a struct . This is why we'll need a function to initialize a new
stack for us. Let's call it new_stack()
// stack.h
/* function to allocate a new stack */
stack new_stack ();
// stack.h
/* function to deallocate memory used by a stack */
void free_stack (stack);
3 - I/O
Defining what we need
Well, there's not much to do with input, but output needs to be implemented. This might look
gadget-ish but, it's not if we want to keep track of our stacks state. So let us have a print()
function !
// stack.h
/* this function will print our stack onto the screen */
void print (stack);
6 - Putting it altogether
Now we need to assemble all those function prototypes into our stack.h file.
#ifndef _STACK_H_
#define _STACK_H_
#include <stdlib.h>
#include <stdio.h>
#define STACK_CHUNK_SIZE 16
typedef struct {
int sp;
int size;
int *items;
} Stack;
typedef Stack* stack;
stack new_stack ();
void free_stack (stack);
int is_empty (stack);
int is_full (stack);
void push (stack, int);
int pop (stack);
void print(stack);
#endif /* _STACK_H_ */
You're now ready to implement all those functions and get yourself a working stack !
Memory management
In this part, we'll simply implement the memory-wise functions we've defined previously.
Let's create a new file named stack.c . This source file will contain the implementation of
every function defined in the previous part.
- new_stack()
This function's purpose is to allocate just enough memory for a new stack. But how to
define a base size if we don't ask the programmer to specify one ? Using a macro, for sure !
// stack.h
#ifndef _STACK_H_
#define _STACK_H_
/* a macro to specify the base size of our stack */
#define STACK_CHUNK_SIZE 16
// ....
Now we got this, let's head back into our stack.c file, and type in the implementation of the
new_stack() function.
#include "stack.h"
stack new_stack() {
printf ("Stack created\n");
stack s = calloc (1, sizeof(Stack));
s->sp = 0;
s->size = STACK_CHUNK_SIZE;
s->items = malloc (STACK_CHUNK_SIZE * sizeof int);
return s;
}
Memory management
10
- free_stack()
Again, this function is meant to free the memory previously allocated to our struct ( stack ).
This is maybe the simplest function to write in this part, look
// stack.c
void free_stack() {
printf ("Stack deleted\n");
free (s->items);
free (s);
}
Memory management
11