For those of us at the old school, dynamic allocation is something expensive and optional! Data structures like this come naturally.
In more complex systems, you have to assume dynamic allocation and deallocation everywhere. And so you rarely encounter code that is this straightforward: these patterns are lost.
Reminds me of the original ls source code: I have it on my laptop somewhere. It doesn't really use generic dynamic allocation. It uses brk to get room at the end of the program for its scratch buffer.
A different world.