0

I've thought about learning a little bit of Zig and was attempting to prototype maintaining a std.ArrayList of a struct that I created, but have been getting error{OutOfMemory}. I've tried using all the Google-Fu that I have to search for various combinations of the error and using structs with ArrayList to no avail.

This question (Malloc to a List of Struct in Zig) seems to be the closest solution, but I'd much rather things be dynamic than me having to allocate more memory than I think I'd need.

Here's the code that I have written, as a test:

const std = @import("std");

const Backtrace = struct {
  node: usize, distance: u8
};

pub fn main() void {
  const allocator = std.heap.page_allocator;
  var backtrace = std.ArrayList(Backtrace).init(allocator);
  defer backtrace.deinit();

  const nodes = [_]usize{1, 3, 5, 7, 9, 11};

  for (nodes) |n,d| {
    std.debug.print("{}: {}\n", .{n, d});
    try backtrace.append(.{.node = n, .distance = @truncate(u8, d)});
  }
}

This code was inspired by this issue (Search ArrayList of Structs in Zig).

Here's the output I get if I run this in the terminal:

$> zig run allocations.zig
allocations.zig:16:5: error: expected type 'void', found 'error{OutOfMemory}'
    try backtrace.append(.{.node = n, .distance = @truncate(u8, d)});
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/zig/0.10.1/lib/zig/std/mem/Allocator.zig:10:19: note: error set declared here
pub const Error = error{OutOfMemory};
                  ^~~~~~~~~~~~~~~~~~
allocations.zig:7:15: note: function cannot return an error
pub fn main() void {
              ^~~~
referenced by:
    comptime_0: /opt/homebrew/Cellar/zig/0.10.1/lib/zig/std/start.zig:59:50
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

Finally, in case it matters, I am on Zig version 0.10.1 installed with Homebrew.

sk3p7ic
  • 3
  • 3

1 Answers1

1

Your main function declaration doesn't allow for errors. Change void to !void:

pub fn main() !void
sigod
  • 3,514
  • 2
  • 21
  • 44
  • Okay, I've been thinking this whole time that the compiler was preemptively anticipating the error or something. So the response I'd gotten was because `append` can throw an error which I wasn't handling? – sk3p7ic Apr 20 '23 at 01:16
  • `append` returns [an error union](https://ziglang.org/documentation/0.10.1/#Error-Union-Type). You need to check for error before you can use the return value. Which you do by using [`try`](https://ziglang.org/documentation/0.10.1/#try). Which is a shortcut for `append() catch |err| return err;`. So, you're returning an error if there's one, but your `main` declaration states that it only returns `void`. You need to return an error union instead. E.g. `!void`. (Or handle the error some other way.) I recommend reading the documentation. – sigod Apr 20 '23 at 01:51