Generic Stack
Part of the Object Oriented Programming section of Coddy's C journey — lesson 60 of 61.
Challenge
EasyA 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 theStackstruct with three members: avoid**array for items, anintfor the top index (next free slot), and anintfor 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 pointerpush— adds an item to the top if there's room (when top is less than capacity)pop— removes and returns the top item, or returnsNULLif the stack is emptypeek— returns the top item without removing it, orNULLif emptyis_empty— returns 1 if the stack has no items, 0 otherwisefree_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:pushfollowed by an integer value,pop, orpeek. Create a stack with capacity 10. Forpush, allocate an integer on the heap and push its pointer. Forpop, retrieve the item, print its value, and free the integer. Forpeek, print the value without removing it. Ifpoporpeekis called on an empty stack, printempty. After all operations, free any remaining items and the stack.
Your program will receive:
- The number of operations
- Each operation on a separate line (
push X,pop, orpeek)
Example output when inputs are 5, then push 10, push 20, peek, pop, pop:
20
20
10Example output when inputs are 3, then pop, push 42, peek:
empty
42Example output when inputs are 4, then push 5, push 15, pop, pop:
15
5Remember 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
1Modular Programming Basics
Header FilesInclude GuardsSource FilesStatic FunctionsRecap: Modular Calculator4Encapsulation
Opaque Pointers ConceptDefining Opaque StructsGetters and SettersValidation in SettersRecap: Secret Box2Objects and Methods
Structs as ObjectsThe 'Self' PointerConst CorrectnessPointer vs ValueHelper MethodsRecap: Point Manager5Project: Simple Bank Account
Project SetupImplementation of Account3Object Lifecycle
Constructor PatternDestructor PatternStack InitializationDeep CopyRecap: String Wrapper6Inheritance via Composition
Struct EmbeddingThe First Member RuleAccessing Parent MembersUpcastingRecap: Shape Hierarchy