#How To Allocate (Static?) Memory

1 messages · Page 1 of 1 (latest)

floral osprey
#

Have gotten far enough in zig that I'm trying to do things like "module level parsed data".

For example I've got this thing:

const Patch = struct {
    stride: usize,
    width: usize,
    data: []Cell, // an enum fwiw, not relevant

    const Self = @This();

    pub fn parse(allocator: Allocator, s: []const u8) !Self {
        var data = try allocator.alloc(Cell, s.len);
        errdefer allocator.free(data);

        // this does the "obvious" thing and parses u8 codes into Cell data
        return Self.parseInto(data, s);
    }

    // other methods elided for brevity
};

Later on I want to have some compiled in static patches:

const init_patch = Patch.parse(std.heap.page_allocator,
    \\ |.......|
    \\ |.......|
    \\ |.......|
    \\ |.......|
    \\ +-------+
) catch @compileError("must parse init_patch");

But this fails with a more or less reasonable:

/home/jcorbin/.local/zig-linux-x86_64-0.11.0-dev.829+68d2f68ed/lib/std/mem/Allocator.zig:128:54: error: unable to evaluate comptime expression
    return self.allocAdvancedWithRetAddr(T, null, n, @returnAddress());
                                                     ^~~~~~~~~~~~~~~~
day17/main.zig:322:39: note: called from here
        var data = try allocator.alloc(Cell, s.len);
                       ~~~~~~~~~~~~~~~^~~~~~~~~~~~~
day17/main.zig:354:35: note: called from here
    const init_patch = Patch.parse(std.heap.page_allocator,
                       ~~~~~~~~~~~^
day17/main.zig:297:34: error: member function expected 2 argument(s), found 1
            .data = try allocator.dupe(self.data),
                        ~~~~~~~~~^~~~~
/home/jcorbin/.local/zig-linux-x86_64-0.11.0-dev.829+68d2f68ed/lib/std/mem/Allocator.zig:307:5: note: function declared here
pub fn dupe(allocator: Allocator, comptime T: type, m: []const T) ![]T {

Which makes sense, since I had misgivings in the first place when choosinng "Heap Allocator" for something at module level.

So is there an allocator that I can use here? Maybe this will work:

var static_slab = [_]u8{8} ** (64 * 1024); // should be enough ;-)
var static_buffer = std.heap.FixedBufferAllocator.init(&static_slab);

// then we pass static_buffer.allocator() later

But maybe there's already some sort of copiler assisted static allocator?

#

update: tried out the fixed static buffer idea, but it fails similarly, trying to call @returnAddress()

rose ether
#

I might be misunderstanding, but have you tried

const static_patch1 =
    \\ |.......|
    \\ |.......|
    \\ |.......|
    \\ |.......|
    \\ +-------+
;
const static_patch2 =
    ...

and then at runtime (in a fn)
const static_patchN = Patch.parse(std.heap.page_allocator, static_patchN) catch ..

floral osprey
#

sure, but then the parse isn't verifed or checked until runtime

rose ether
#

nvm then :)

floral osprey
#

at this point , I'll almost certainly have to fall back to a runtime parse here, but I'm not so much interested in What It Takes To Work, and more interested in how to construct module-level static data in general 😉

rose ether
#

do a test{} and use std.testing.allocator ?

floral osprey
#

you mean to validate the data, but then it still ends up being parsed at runtime in the main app, sure but that's also not module level static data initialization 😉

trail notch
#

Sounds like you're looking for comptime allocator which isn't a thing atm, but i did see that it is considered since it could be useful for comptime processing

floral osprey
#

excellent, any issue tracking that? would like to subscribe

rose ether
floral osprey
#

awesome, ty for link 🙂

quick bolt
#

Try:

const init_patch = blk: {
    const data =
        <%multiline string literal%>
    ;
    const static = struct {
        var buf: [data.len]u8 = undefined;
    };
    break :blk Patch.parseInto(&static.buf, data) catch unreachable;
};