B
Barry Schwarz
Original code as requested - this has been changed quite a bit since.
I'll post an updated one soon.
#include <stdio.h>
#include <stdlib.h>
/* stack element */
typedef struct stack_element_t {
void* payload;
struct stack_element_t * next;
} stack_element_t;
/* stack */
typedef struct stack_t {
stack_element_t * tos;
size_t size;
} stack_t;
/* initialise stack object */
stack_t *
stack_init()
{
stack_t* stack;
stack = malloc(sizeof(stack_t));
stack->tos = NULL;
stack->size = 0;
return stack;
}
/* pop value from stack */
void*
stack_pop(stack_t* stack)
{
stack_element_t* element;
if (stack->size == 0)
return NULL;
element = stack->tos;
stack->tos = element->next;
void* result = element->payload;
Unless you have a C99 compiler and don't need help from anyone who
doesn't, your object definitions need to appear before any statements.
free(element);
stack->size--;
return result;
}
/* destroy stack */
void
stack_destroy(stack_t* stack)
{
while((void*)stack_pop(stack) != NULL);
The cast serves no purpose. Any type of object pointer can be
compared against NULL.
free(stack);
}
/* push element onto stack */
void
stack_push(stack_t* stack, void* value)
{
stack_element_t* entry;
entry = malloc(sizeof(stack_element_t));
entry->next = stack->tos;
entry->payload = value;
stack->tos = entry;
stack->size++;
}
/* entry point */
int
main()
{
stack_t* stack;
stack = stack_init();
printf("size pre-push: %d\n", stack->size);
stack->size is a size_t. That is unsigned and need not be the same
size as an int. If size_t is actually unsigned long and if a long is
larger than an int, this would invoke undefined behavior. If you
don't have C99 (which has %zu for size_t) then you should cast the
value to match the format. The usual recommendation is to use %lu and
cast to unsigned long.
stack_push(stack, "entry 1");
stack_push(stack, "entry 2");
stack_push(stack, "entry 3");
printf("size post-push: %d\n", stack->size);
printf("%s\n", (char*)stack_pop(stack));
This cast is appropriate.