#Using an arena with std.testing.allocator

1 messages · Page 1 of 1 (latest)

runic estuary
#

I'm trying to use an arena with std.testing.allocator, but I get a recursive panic:

$ zig test test.zig
Segmentation fault at address 0x8
aborting due to recursive panic
error: the following test command crashed:
/Users/aaron/git/prizm/.zig-cache/o/efd75e2769c823e5b8e260e421b13c1d/test --seed=0xcb498a9a

I've reduced the program to this:

const std = @import("std");

pub const CFG = struct {
    arena: std.heap.ArenaAllocator,
    alloc: std.mem.Allocator,

    pub fn init(mem: std.mem.Allocator) !*CFG {
        // Create an arena
        var arena = std.heap.ArenaAllocator.init(mem);
        const alloc = arena.allocator();

        // Create ourself without using the arena
        const cfg = try mem.create(CFG);

        cfg.* = CFG {
            .arena = arena,
            .alloc = alloc,
        };
        return cfg;
    }

    pub fn makeBlock(self: *CFG) !void {
        _ = try self.alloc.create(BasicBlock);
        return;
    }

    pub fn deinit(self: *CFG) void {
        self.arena.deinit();
    }
};

pub const BasicBlock = struct {
    name: u64,
};

test "basic block two instruction" {
    const cfg = try CFG.init(std.testing.allocator);
    _ = try cfg.makeBlock();
    defer cfg.deinit();
}

I am really not sure what I'm doing wrong.

Zig version is this:

$ zig version
0.14.0-dev.2271+f845fa04a

Any help would be appreciated. Thanks!

fiery heath
#

only store the arena in CFG, don't store the allocator

#

the reason is that std.mem.Allocator contains a pointer to the actual allocator implementation, which in this case is the arena

#

but you call allocator() inside CFG.init, which means it holds a pointer to the local arena variable from that function, and that pointer isn't valid anymore after that function returns