Click on list_stack.c to get source.
/* File: CExamples/OO_pgm_in_C_new/list_stack.c */
#include <stdio.h>
#include <stdlib.h>
#include "stack.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 *LS; /* the data struct for stack is simply
                            a pointer to the first cell */

typedef LS *LSptr; /* 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. */

stackptr new_stack()
/* This function is the interface from the abstract object to the D.S.
   it creates a stack and the list_stack */
{stackptr sptr;
 /* declare the functions that will implement the stack operations */
 int  list_isempty(stackptr);
 void list_push   (int, stackptr);
 int  list_pop    (stackptr);
 stackptr list_clone (stackptr);

 /* 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;

 /* allocate memory for the list_stack and initialize */
 sptr->objptr = malloc(sizeof(LS));
 /* see (b) in delete_stack for corresponding free */

 *((LSptr)sptr->objptr) = NULL;
 /* must typecast as LSptr before selection: objptr has type void*;
    note: conversion from and to type void* is permissible for all pointers */
 return sptr;
}/* end new_stack */


void delete_stack( stackptr sptr )
/* Assumes that sptr is the result of new_stack */
{LSptr lsptr;
 struct cell *curr, *prev;

 lsptr = (LSptr)sptr->objptr;
 curr = *lsptr;
 while(curr != NULL)
   {prev = curr; curr = curr->next; free(prev); /* (c) */
   }
 free(lsptr); /* (b) */
 free(sptr); /* (a) */
}/* end delete_stack */


/* The following three functions define the list_stack operations */
int list_isempty(stackptr sptr)
{return( (*(LSptr)sptr->objptr) == NULL );
}/* end list_is_empty */

void list_push(int i, stackptr sptr)
{LSptr lsptr, lsptr2;
 struct cell *cellptr;

 lsptr = (LSptr)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)
{LSptr lsptr; LS ls2;
 int topvalue;

 lsptr = (LSptr)sptr->objptr;
 ls2 = *lsptr;
 *lsptr = ls2->next;
 
 topvalue = ls2->content;
 free(ls2);
 return topvalue;
}/* end list_pop */

stackptr list_clone(stackptr sptr_in)
{LSptr lsptr; stackptr sptr;
 struct cell *curr; /* iterator for list that is passed as arg */
 struct cell *copy; /* iterator for copy of that list */

 /* 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;

 /* allocate memory for the list_stack and initialize */
 sptr->objptr = malloc(sizeof(LS));
 /* see (b) in delete_stack for corresponding free */

 lsptr = (LSptr)sptr_in->objptr;
 curr = *lsptr;
 if ( curr == NULL)
    /* no cells in argument list */
    *((LSptr)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;
     *((LSptr)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 */