How does std.heap.page_allocator.dupe work

what are its memory implications please

From Zig standard library (github):

/// This allocator makes a syscall directly for every allocation and free.
/// Thread-safe and lock-free.
pub const page_allocator = if (builtin.target.isWasm())
    Allocator{
        .ptr = undefined,
        .vtable = &WasmPageAllocator.vtable,
    }
else if (builtin.target.os.tag == .freestanding)
    root.os.heap.page_allocator
else
    Allocator{
        .ptr = undefined,
        .vtable = &PageAllocator.vtable,
    };

source: zig/lib/std/heap.zig at master · ziglang/zig · GitHub

Well, let’s check what std.heap.page_allocator is in the first place.

/// This allocator makes a syscall directly for every allocation and free.
/// Thread-safe and lock-free.
pub const page_allocator = if (builtin.target.isWasm())
    // snip
else
    Allocator{
        .ptr = undefined,
        .vtable = &PageAllocator.vtable,
    };

So, it’s in fact just a std.mem.Allocator that points to the PageAllocator’s “vtable”. So the std.heap.page_allocator.dupe we’re looking at is in fact just std.mem.Allocator.dupe. What does that look like?

/// Copies `m` to newly allocated memory. Caller owns the memory.
pub fn dupe(allocator: Allocator, comptime T: type, m: []const T) ![]T {
    const new_buf = try allocator.alloc(T, m.len);
    @memcpy(new_buf, m);
    return new_buf;
}

So, it’s pretty much exactly what it says on the tin: It allocates new memory and copies the buffer contents to it, basically what you would do in the absence of this function. Its memory implications are “equally sized array gets allocated”.

2 Likes