Click on list_stack_without_newstack.c to get source.
/* File: CExamples/OO_pgm_in_C_new/list_stack_without_newstack.c */
#include <stdio.h>
#include <stdlib.h>
#include "stack_with_delete.h"
/* This is the Data Structure used to implement the stack:
the contents of the first cell in the list contains the top elem
and next points to the cells below in the stack */
struct cell { int content;
struct cell *next;
};
typedef struct cell *cellptr; /* the data struct for stack is simply
a (sentinel) pointer to the first cell */
typedef cellptr *cellptrptr; /* a pointer to that pointer is stored
in the abstract class. With this
argument, push and pop can update
the pointer to the first cell. */
void list_delete_stack( stackptr self )
/* Assumes that sptr is the result of new_stack */
{extern const stack empty_list_stack; /* forward declare */
cellptrptr lsptr;
struct cell *curr, *prev;
if(self != &empty_list_stack) /* prevent delete of prototype */
{lsptr = (cellptrptr)self->objptr;
curr = *lsptr;
while(curr != NULL)
{prev = curr; curr = curr->next; free(prev); /* (c) */
}
}
free(lsptr); /* (b) */
free(self); /* (a) */
}/* end list_delete_stack */
/* The following three functions define the list_stack operations */
int list_isempty(stackptr sptr)
{return( (*(cellptrptr)sptr->objptr) == NULL );
}/* end list_is_empty */
void list_push(int i, stackptr sptr)
{cellptrptr lsptr, lsptr2;
struct cell *cellptr;
lsptr = (cellptrptr)sptr->objptr; lsptr2 = lsptr;
cellptr = malloc(sizeof(struct cell));
/* no check for memory overflow
see (c) in delete_stack for correponding delete */
cellptr->content = i;
cellptr->next = *lsptr2; /* note the dereference
this is where the pointer to the first cell is stored */
*lsptr2 = cellptr;
}/* end list_push */
int list_pop(stackptr sptr)
{cellptrptr lsptr; cellptr ls2;
int topvalue;
lsptr = (cellptrptr)sptr->objptr;
ls2 = *lsptr;
*lsptr = ls2->next;
topvalue = ls2->content;
free(ls2);
return topvalue;
}/* end list_pop */
stackptr list_clone(const struct stackstruct* sptr_in)
{cellptrptr lsptr; stackptr sptr;
struct cell *curr; /* iterator for list that is passed as arg */
struct cell *copy; /* iterator for copy of that list */
extern const stack empty_list_stack; /* forward declare */
if(sptr_in == &empty_list_stack) printf("\nCloning the proto-type empty_list_stack\n");
/* allocate memory for the stack */
sptr = (stackptr)malloc(sizeof(stack));
/* see (a) in delete_stack for corresponding free */
/* set the function pointers to list functions */
sptr->is_empty = list_isempty;
sptr->push = list_push;
sptr->pop = list_pop;
sptr->clone = list_clone;
sptr->delete_stack = list_delete_stack;
/* allocate memory for the list_stack and initialize */
sptr->objptr = malloc(sizeof(cellptr));
/* see (b) in delete_stack for corresponding free */
lsptr = (cellptrptr)sptr_in->objptr;
curr = *lsptr;
if ( curr == NULL)
/* no cells in argument list */
*((cellptrptr)sptr->objptr) = NULL;
else
{/* must copy cells: first cell
see (c) in delete_stack for corresponding free */
copy = (struct cell*)malloc(sizeof(struct cell));
copy->content = curr->content;
*((cellptrptr)sptr->objptr) = copy; /* link data struct to it */
curr = curr->next;
while(curr != NULL)
{/* copy 2nd, 3rd, ... cells
see (c) in delete_stack for corresponding free */
copy->next = (struct cell*)malloc(sizeof(struct cell));
copy = copy->next;
copy->content = curr->content;
curr = curr->next;
}
copy->next = NULL;
}
return sptr;
}/* end list_clone */
/* There is no constructor newstack().
Instead there his one linkable variable empty_list_stack,
whose clone() can be used to make new empty array stacks.
See main2.c for usage. */
static const void* sentinel = NULL;
const stack empty_list_stack
= {/* initialize */
&sentinel
,list_isempty
,list_push
,list_pop
,list_clone
,list_delete_stack
}; /* end stack empty_list_stack */