Hello, I’m trying to use the arena allocator to allocate some temporary pages in memory, then deallocate everything after flushing these pages to disk.
The fields of my struct look like this:
fd: std.os.fd_t,
root_ptr: u64,
mmap: struct {
file_size: u64,
mmap_size: u64,
chunks: std.ArrayList([]align(page_size) u8),
},
tmp: struct {
n_flushed: u64,
pages: std.ArrayList([]u8),
arena: std.heap.ArenaAllocator,
},
allocator: std.mem.Allocator,
I initialize some of these fields like this:
var self: Self = undefined;
self.fd = try std.os.open(path, std.os.O.RDWR | std.os.O.CREAT, 0o0644);
self.mmap.chunks = std.ArrayList([]align(page_size) u8).init(allocator);
self.tmp.pages = std.ArrayList([]u8).init(allocator);
self.tmp.arena = std.heap.ArenaAllocator.init(allocator);
self.allocator = self.page.arena.allocator();
errdefer self.deinit();
// some mmap related stuff...
But when I try to allocate a page like this inside some other function:
var tmp_page = try self.allocator.alloc(u8, page_size)
I get this error:
run test: error: Segmentation fault at address 0x0
/home/luiz/zig/zig-linux-x86_64-0.12.0-dev.415+5af5d87ad/lib/std/heap/arena_allocator.zig:186:77: 0x240cb1 in alloc
(test)
const cur_alloc_buf = @as([*]u8, @ptrCast(cur_node))[0..cur_node.data];
^
/home/luiz/zig/zig-linux-x86_64-0.12.0-dev.415+5af5d87ad/lib/std/mem/Allocator.zig:215:29: 0x23f4ec in allocBytesWit
hAlignment__anon_5707 (test)
// The Zig Allocator interface is not intended to solve alignments beyond
^
/home/luiz/zig/zig-linux-x86_64-0.12.0-dev.415+5af5d87ad/lib/std/mem/Allocator.zig:211:40: 0x23b44d in allocWithSize
AndAlignment__anon_4391 (test)
return self.allocBytesWithAlignment(alignment, byte_count, return_address);
^
/home/luiz/zig/zig-linux-x86_64-0.12.0-dev.415+5af5d87ad/lib/std/mem/Allocator.zig:137:75: 0x22acc1 in alloc__anon_2
412 (test)
comptime optional_alignment: ?u29,
^
/home/luiz/Documents/codes/zig/zdb/src/DiskPager.zig:102:44: 0x231df9 in new (test)
var tmp_page = try self.allocator.alloc(u8, page_size);
^
If instead I allocate like this:
var tmp_page = try self.tmp.arena.allocator().alloc(u8, page_size);
Everything works fine, but I would much prefer to have an allocator field separated as it is part of the api I’m planing. How can I solve this problem when using the self.allocator
field?