As I continue to get my feet wet with Zig, I find myself greatly admiring the paradigm of no hidden allocations1. Any function that needs to allocate heap memory must receive a mem.Allocator2. This is more explicit than the ability to call malloc() at any depth of the call stack in C and lets (and forces) the calling code decide what allocator to use. So on the other hand, the programmer generally knows that any function without an Allocator argument only uses stack memory, though of course nothing stops a Zig function from initializing a new Allocator. This is not a guarantee, but at least there is a blessed pattern for it.
In my previous post, I mentioned working on a Netlink library in Zig. Pretty much every Netlink library I have seen manages an internal byte buffer for communication with the kernel, and mine is no different.
Programs that use Netlink often make multiple request+response roundtrips to the kernel. The buffer is of course necessary for the recv() call, and it is more efficient to reuse the buffer than create a new one for each response.