7.12.2. Dynamic Stack Implementation

array, stack, new
Time: 00:02:47 | Download: Large, Large (CC), Small | Streaming, Streaming (CC) | Slides: PDF, PPTX
Review

The following example implements a stack as a structure with an array field. Unlike the previous automatic structure version, the dynamic version allocates the array dynamically on the heap with the new operator. Surprisingly, the change requires few modifications to the previous version. In both versions, the driver creates a stack structure object as an automatic or local variable. However, in the dynamic version, the data array is a pointer rather than an array, allowing the client program to specify the stack's size when creating it.

Dynamic Stack Header File

array, stack, pass by pointer, struct, prototypes
struct dstack
{
	char*	st;
	int	sp;
	int	max;
};

dstack	make_stack(int size);
void	init_stack(dstack* s, int size);
void	push(dstack* s, char data);
char	pop(dstack* s);
int	size(dstack* s);
char	peek(dstack* s);
void	cleanup(dstack* s);
A picture illustrating the relationship between three stack components. The stack array becomes a pointer pointing to the array, the array has a maximum size of 'max,' and the stack pointer is initialized to 0.
dstack.h (dynamic structure version). The figure uses the term pointer in two distinct ways. The array variable, st, is a character pointer storing the address of an array allocated on the heap. The stack pointer, sp, is an integer, used as an array index, that points to the top of the stack. Converting the automatic to the dynamic version requires four significant changes:
  1. A pointer replaces the stack array (blue), allowing the user to specify the stack's size when creating the array.
  2. A structure field, max, replaces the symbolic constant SIZE (pink), allowing the stack object to "remember" its maximum size so the push function can detect and prevent a stack overflow (the if-statement).
  3. The client program passes the stack's size to make_stack and init_stack through an added argument called size (green).
  4. The dynamic version must provide a new function, named cleanup (yellow), to delete the dynamically allocated array, and the user must remember to call that function. (Object-oriented programming solves these problems more elegantly with a function called a destructor, which we explore in Chapter 9.)
The pointer parameters remain unchanged from the previous version. They bind the functions to the object on which they operate.

Dynamic Stack Functions

array, stack, make_stack, init_stack, push, pop, size, peek, new, delete[]
Construction Typical Operations
dstack make_stack(int size)
{
    dstack	temp;
    temp.st = new char[size];
    temp.sp = 0;
    temp.max = size;

    return temp;
}

void init_stack(dstack* s, int size)
{
    s->st = new char[size];
    s->sp = 0;
    s->max = size;
}
void push(dstack* s, char data)
{
    if (s->sp < s->max)
        s->st[s->sp++] = data;
    else
        throw "Stack Overflow";
}

char pop(dstack* s)
{
    if (s->sp > 0)
        return s->st[--(s->sp)];
    else
        throw "Stack Underflow";
}
 
Optional Operations Destruction
int size(dstack* s)
{
    return s->sp;
}

char peek(dstack* s)
{
    return s->st[s->sp - 1];
}
void cleanup(dstack* s)
{
    delete[] s->st;
}
 
 
 
 
 
dstack.cpp (dynamic structure version). The dynamic structure version organizes the seven stack functions into four functional groups. Changes from the previous stack example are noted:
make_stack and init_stack
Adds a size parameter, dynamically allocates the stack array with new, sets max, the maximum size of the stack, to size, and sets the stack pointer, sp, to 0
push
Replaces the SIZE constant with the max structure field in the if-statement
pop, size, and peek
Unchanged
cleanup
Added; deletes the heap memory allocated with new

Making and Using A Dynamic Stack

stack, client
#include <iostream>
#include "dstack.h"
using namespace std;

int main()
{
	//dstack s = make_stack(10);
	dstack	s;
	init_stack(&s, 10);

	push(&s, 'x');
	push(&s, 'y');
	push(&s, 'z');

	char c = peek(&s);
	cout << c << endl;

	c = pop(&s);
	cout << c << endl;

	while (size(&s) > 0)
		cout << pop(&s) << endl;
	
	cleanup(&s);

	return 0;
}
dtest.cpp (dynamic structure version). The driver demonstrates the operations of a simple stack client. The highlighted statements illustrate two methods for making a stack. The first method, a call to the make_stack function, is inauthentic but consistent with the previous Time structure examples. The init_stack function is more authentic and sets the stage for a Stack Class implementation in Chapter 9.

Downloadable Dynamic Stack Code

array, stack, dstack.h, dstack.cpp, dtest.cpp
ViewDownloadComments
dstack.h dstack.h struct specifications and function prototypes
dstack.cpp dstack.cpp Defines the make_stack, init_stack, push, pop, size, and peek function for an array-based stack implementation. The functions demonstrate the implicit use of the this pointer.
dtest.cpp dtest.cpp A test driver for the structure-based stack example