Here's the second draft of my ADT stack code which I posted here before after carrying out most of the improvements suggested there.
I decided to expose a function called resize_stack
to adjust the size of the stack as desired by the user instead of doing it automatically.
stacklib.h
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#ifndef STACKLIB_H
#define STACKLIB_H
/* generic type pushed item_to the stack */
/* in this case it's just an int */
typedef int item_t;
/* our stack data type */
typedef struct {
size_t size;
size_t capacity;
item_t *elements;
} stack;
/* interface to our new stack data type */
stack* create_stack(size_t capacity);
int push_stack(stack *mystack, item_t data);
item_t* pop_stack(stack *mystack);
void delete_stack(stack *mystack);
stack* resize_stack(stack *mystack, size_t capacity);
#endif
stacklib.c
#include "stacklib.h"
/* a helper function to handle exceptions */
void handle_error(const char* message)
{
if(errno) {
perror(message);
} else {
printf("Error: %s\n", message);
}
exit(1);
}
stack* create_stack(size_t capacity)
{
stack *stack_ptr = malloc(sizeof(stack));
if(stack_ptr == NULL)
handle_error("Error while allocating memory.");
item_t *elements_ptr = malloc(capacity*sizeof(item_t));
if(elements_ptr == NULL) {
free(stack_ptr);
handle_error("Error while allocating memory.");
}
stack_ptr->size = 0;
stack_ptr->capacity = capacity;
stack_ptr->elements = elements_ptr;
return stack_ptr;
}
void delete_stack(stack *mystack)
{
free(mystack->elements);
free(mystack);
}
/* Returns 0 on success, 1 on failure */
int push_stack(stack *mystack, item_t data)
{
/* stack is full! */
if(mystack->size == mystack->capacity)
return 1;
mystack->elements[mystack->size++] = data;
return 0;
}
/* Returns a pointer to the popped data or NULL if the stack is empty */
item_t* pop_stack(stack *mystack)
{
if(mystack->size == 0) {
return NULL;
} else {
return &mystack->elements[--mystack->size];
}
}
/* Returns a pointer to the adjusted stack or NULL on failure */
stack* resize_stack(stack *mystack, size_t capacity)
{
item_t *tmp = realloc(mystack->elements, sizeof(item_t) * capacity);
if(tmp == NULL)
return NULL;
mystack->elements = tmp;
mystack->capacity = capacity;
if(mystack->size > capacity)
mystack->size = capacity;
return mystack;
}
main.c
#include "stacklib.h"
int main(void){
stack *my_stack = create_stack(20);
item_t i;
for(i = 0; i < 20; i++) {
push_stack(my_stack, i);
}
resize_stack(my_stack, 10);
item_t res, *item ;
while((item = (item_t*)pop_stack(my_stack)) != NULL) {
res = *item;
printf("data: %d\n", res);
}
delete_stack(my_stack);
printf("last item popped was %d\n", res);
return 0;
}