Zig makes allocation an explicit runtime concern:
var list = std.ArrayList(i32).init(allocator);
where allocator is a
runtime value implementing the allocator interface.
fn parseJson(allocator: Allocator, input: []const u8) !JsonValue
Zig
forces the caller to decide since allocator is part of the function contract. And this is
consistent everywhere in Zig. Effectively speaking, this is
universal, explicit & mandated dependency injection for memory management as opposed to to classic C++ STL allocators.
Sorry sir, I have a nostalgic fondness for C++ - it was my first language, but it just doesn't compare for flexible allocation convenience compared to Zig.