Implementing Stack Data Structures in C: Array-Based and Linked List Approaches

A stack is a linear data structure that restricts insertions and deletions to a single endpoint—referred to as the top—while the opposite fixed end is the bottom. When no elements are present, its an empty stack, and its fundamental behavior follows Last-In-First-Out (LIFO) semantics.

Static Stack Using Contiguous Memory

This implementation leverages a dynamically allocated array with an integer index tracking the top position.

Structure Definition

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef int ElementType;

typedef struct {
    ElementType *buffer;
    int capacity;
    int current_size;
} ArrayStack;

Initialization

ArrayStack* create_array_stack(int max_elements) {
    if (max_elements <= 0) return NULL;
    
    ArrayStack* s = malloc(sizeof(ArrayStack));
    if (!s) return NULL;
    
    s->buffer = malloc(max_elements * sizeof(ElementType));
    if (!s->buffer) {
        free(s);
        return NULL;
    }
    
    s->capacity = max_elements;
    s->current_size = 0;
    return s;
}

Push Operation

int push(ArrayStack* s, ElementType value) {
    if (!s || s->current_size >= s->capacity) return -1;
    s->buffer[s->current_size++] = value;
    return 0;
}

Pop Operation

int pop(ArrayStack* s, ElementType* out_value) {
    if (!s || s->current_size == 0) return -1;
    *out_value = s->buffer[--s->current_size];
    return 0;
}

Peek and Utility Functions

int peek(const ArrayStack* s, ElementType* out_value) {
    if (!s || s->current_size == 0) return -1;
    *out_value = s->buffer[s->current_size - 1];
    return 0;
}

int is_empty(const ArrayStack* s) {
    return s ? (s->current_size == 0) : -1;
}

int is_full(const ArrayStack* s) {
    return s ? (s->current_size == s->capacity) : -1;
}

void clear_stack(ArrayStack* s) {
    if (s) s->current_size = 0;
}

void destroy_array_stack(ArrayStack* s) {
    if (s) {
        free(s->buffer);
        free(s);
    }
}

Dynamic Stack Using Singly Linked Nodes

In this version, each node holds one element and a pointer to the next; the head of the list serves as the stack top.

Node and Stack Definitions

struct StackNode {
    ElementType val;
    struct StackNode* next;
};

typedef struct {
    struct StackNode* head;
} LinkedStack;

Initialization

LinkedStack* create_linked_stack(void) {
    LinkedStack* s = malloc(sizeof(LinkedStack));
    if (!s) return NULL;
    s->head = NULL;
    return s;
}

Push Operation

int push_linked(LinkedStack* s, ElementType value) {
    if (!s) return -1;
    
    struct StackNode* new_node = malloc(sizeof(struct StackNode));
    if (!new_node) return -1;
    
    new_node->val = value;
    new_node->next = s->head;
    s->head = new_node;
    return 0;
}

Pop Operation

int pop_linked(LinkedStack* s, ElementType* out_value) {
    if (!s || !s->head) return -1;
    
    struct StackNode* temp = s->head;
    *out_value = temp->val;
    s->head = temp->next;
    free(temp);
    return 0;
}

Peek and Utility Functions

int peek_linked(const LinkedStack* s, ElementType* out_value) {
    if (!s || !s->head) return -1;
    *out_value = s->head->val;
    return 0;
}

int is_empty_linked(const LinkedStack* s) {
    return s ? (s->head == NULL) : -1;
}

void destroy_linked_stack(LinkedStack* s) {
    if (!s) return;
    
    struct StackNode* current = s->head;
    while (current != NULL) {
        struct StackNode* next = current->next;
        free(current);
        current = next;
    }
    free(s);
}

Example Usage

int main() {
    // Test array-based stack
    ArrayStack* arr_stack = create_array_stack(5);
    if (arr_stack) {
        push(arr_stack, 10);
        push(arr_stack, 20);
        push(arr_stack, 30);
        
        ElementType val;
        while (pop(arr_stack, &val) == 0) {
            printf("Popped: %d\n", val);
        }
        destroy_array_stack(arr_stack);
    }
    
    // Test linked stack
    LinkedStack* link_stack = create_linked_stack();
    if (link_stack) {
        push_linked(link_stack, 100);
        push_linked(link_stack, 200);
        
        while (pop_linked(link_stack, &val) == 0) {
            printf("Popped: %d\n", val);
        }
        destroy_linked_stack(link_stack);
    }
    
    return 0;
}

Tags: C data-structures stack algorithms memory-management

Posted on Thu, 07 May 2026 06:50:15 +0000 by yakabod