Leak detection with juicy main init.gpa?

How does one call the leak detection function (gpa.deinit()) with when I’m passed a gpa through the juicy main init argument?

The usual way without init.gpa, you’d do (from the docs):

const std = @import("std");

pub fn main() !void {
    var debug_allocator = std.heap.DebugAllocator(.{}){};
    defer std.debug.assert(debug_allocator.deinit() == .ok);

    const gpa = debug_allocator.allocator();

    const u32_ptr = try gpa.create(u32);
    _ = u32_ptr; // silences unused variable error

    // oops I forgot to free!
}

Reading the docs for std.Process.Init.gpa, it’s suggested that this allocator would be a debug allocator too:

    /// A default-selected general purpose allocator for temporary heap
    /// allocations. Debug mode will set up leak checking if possible.
    /// Threadsafe.
    gpa: Allocator,

So I start by:

pub fn main(init: std.process.Init) !void {
    const gpa = init.gpa;
    // but this is an Allocator interface.. how do I call the deinit?
}

But how do I call its deinit()? I tried pretty hard to find this from the docs.

I’m on zig 0.16.0.

pretty sure juicy main does it for you

You’re right, it does! I verified in a smaller zig init project.

I must’ve somehow wired it wrong in my larger application. It’s a sokol app that I start like:

pub fn main(process_init: std.process.Init) !void {
    process_gpa = process_init.gpa;
    const args = try process_init.minimal.args.toSlice(process_init.gpa);

    const u32_ptr = try process_init.gpa.create(u32);
    _ = u32_ptr; // no leak detected for this alloc?!

    // Get and print them!
    if (args.len >= 2) {
        lua_entry_script = args[1];
    }

    sapp.run(.{
        .init_cb = init,
        .frame_cb = frame,
        .cleanup_cb = cleanup,
        .event_cb = input,
        .width = 2 * 640,
        .height = 2 * 480,
        .sample_count = 1,
        .icon = .{ .sokol_default = true },
        .window_title = "zig2d!",
        .logger = .{ .func = slog.func },
    });
}

What optimize mode are you compiling it in? Leak checking only happens in Debug and ReleaseSafe.

Also, you’re leaking args here too; toSlice expects an arena allocator.

const arena = process_init.arena.allocator();
const args = try process_init.minimal.args.toSlice(arena);
1 Like

I’m building with the default Debug.

I did see that other leak too, but thought there was something special about it as I didn’t get a leak error about that either. :slightly_smiling_face:

I didn’t check in too much detail yet but I wonder if the sokol app shutdown process somehow skips the zig deinit that’d normally run after main exits. I guess that’d happen f.ex. when exiting with std.process.exit(0).

3 Likes