Menu
Coddy logo textTech

Generic Stack

Part of the Object Oriented Programming section of Coddy's C journey — lesson 60 of 61.

challenge icon

Challenge

Easy

A stack is a fundamental data structure that follows the Last-In-First-Out (LIFO) principle — the last element added is the first one removed. Think of a stack of plates: you add to the top and remove from the top.

Let's build a Generic Stack — a versatile data structure that can store any type of data using void* pointers. Your stack will follow the Last-In-First-Out principle, complete with all the essential operations.

You'll organize your code across three files:

  • stack.h: Define the Stack struct with three members: a void** array for items, an int for the top index (next free slot), and an int for capacity. Declare function prototypes for creating a stack (takes a capacity), pushing an item, popping an item, peeking at the top item, checking if the stack is empty, and freeing the stack.
  • stack.c: Implement your generic stack:
    • create_stack — allocates a Stack on the heap, allocates the items array with the given capacity, initializes top to 0, and returns the pointer
    • push — adds an item to the top if there's room (when top is less than capacity)
    • pop — removes and returns the top item, or returns NULL if the stack is empty
    • peek — returns the top item without removing it, or NULL if empty
    • is_empty — returns 1 if the stack has no items, 0 otherwise
    • free_stack — frees the items array first, then the Stack struct itself
  • main.c: Read the number of operations to perform. Then for each operation, read a command: push followed by an integer value, pop, or peek. Create a stack with capacity 10. For push, allocate an integer on the heap and push its pointer. For pop, retrieve the item, print its value, and free the integer. For peek, print the value without removing it. If pop or peek is called on an empty stack, print empty. After all operations, free any remaining items and the stack.

Your program will receive:

  1. The number of operations
  2. Each operation on a separate line (push X, pop, or peek)

Example output when inputs are 5, then push 10, push 20, peek, pop, pop:

20
20
10

Example output when inputs are 3, then pop, push 42, peek:

empty
42

Example output when inputs are 4, then push 5, push 15, pop, pop:

15
5

Remember that your stack stores void* pointers — the caller is responsible for allocating and freeing the actual data. When popping, cast the returned void* back to int* to access the value. Use strcmp from <string.h> to compare command strings.

Try it yourself

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

int main() {
    int n;
    scanf("%d", &n);
    
    // TODO: Create a stack with capacity 10
    
    // TODO: Process each operation
    for (int i = 0; i < n; i++) {
        char command[10];
        scanf("%s", command);
        
        if (strcmp(command, "push") == 0) {
            int value;
            scanf("%d", &value);
            // TODO: Allocate an integer on the heap and push its pointer
        }
        else if (strcmp(command, "pop") == 0) {
            // TODO: Pop the item
            // - If not NULL, print value and free the integer
            // - If NULL (empty stack), print "empty"
        }
        else if (strcmp(command, "peek") == 0) {
            // TODO: Peek at the top item
            // - If not NULL, print value (don't remove or free)
            // - If NULL (empty stack), print "empty"
        }
    }
    
    // TODO: Free any remaining items in the stack
    // TODO: Free the stack itself
    
    return 0;
}

All lessons in Object Oriented Programming