A lightweight, zero-dependency CLI Task Manager engineered to demonstrate low-level pointer arithmetic, safe heap management, and O(1) tail-insertion mechanics.
.
├── main.c # App entry point, master execution loop, and CLI menu router
├── tasks.c # Core business logic, linked-list operations, and File I/O
├── tasks.h # Struct definitions, enums, and public function prototypes
├── Makefile # Automation script for clean building, running, and leak testing
└── tasklist.txt # (Auto-generated) Persistent pipe-delimited session database
Standard singly-linked lists require O(n) traversal to append an item to the end. By maintaining a single pointer to the tail, and mapping tail->next back to the head, this application achieves O(1) insertions at both ends of the list:
┌────────────────────────────────────────┐
▼ │
┌───────────┐ ┌───────────┐ ┌─────┴─────┐
│ Head │ ───► │ Node 2 │ ───►... │ Tail │
│ (Task #1) │ │ (Task #2) │ │ (Task #N) │
└───────────┘ └───────────┘ └───────────┘
▲
TaskManager->tail ────────────────────────────────┘
- O(1) Appending: Instantly attach new items whether the list has 5 tasks or 50,000.
- Triage Priority: Categorize tasks as
[ ! ] HIGH,[ - ] MEDIUM, or[ v ] LOW. - Date Tracking: Built-in integer parsing for custom
DD/MM/YYYYdeadlines. - Safe Memory Lifecycle: Strict
malloc/strdupheap allocation paired with a recursivefreeList()sweep to guarantee zero memory leaks upon exit. - Session Persistence: Automatically dumps your live linked list into a serialized text file on quit, and reconstructs the pointer map on boot.
The application serializes memory into a flat text file using standard pipe (|) delimiters.
- Row 1 (Metadata):
[Total_List_Size]|[Next_Assigned_ID] - Row 2+ (Nodes):
[ID]|[Task_Name]|[Priority_Enum]|[Is_Completed]|[DD]/[MM]/[YYYY]
Example data payload:
4|5
1|Gaming|2|0|23/6/2026
2|Going on a Run|1|0|30/7/2025
3|Job Searching|3|0|11/3/2025
4|Work|2|1|14/5/2025
This project includes a Makefile to simplify compilation, execution, and memory testing.
Compile the source files and generate the executable:
makeCompile (if changes were made) and launch the task manager immediately:
make runRun the suite through Valgrind to monitor dynamic heap allocation and ensure freeList() executes safely:
make valgrindRemove compiled object (.o) files and binary executables to reset your directory:
make cleanOn Ubuntu/Debian Linux:
sudo apt update
sudo apt install valgrindOn macOS (using Homebrew):
brew install valgrind(Note for macOS: Valgrind can sometimes be finicky on newer Apple Silicon M1/M2/M3 chips. If it gives you trouble, developers often use leaks --atExit -- ./todomanager instead).