I use a double-ended stack allocator for most allocations in personal C projects. The second end adds a significant amount of flexibility; temporary allocations can accumulate at one end of the stack without preventing a longer-lasting allocation from being made later (yet before the temporary allocations can be freed) on the other end.