You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Zig中分配合法std.ArrayList时为何出现错误?

Zig std.ArrayList 存储自定义struct报错解决

问题情况

使用Zig 0.10.1版本,尝试用std.ArrayList维护自定义struct时,遇到error{OutOfMemory}编译错误。希望实现动态分配内存,而非预分配过多空间。

测试代码:

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)});
  }
}

终端报错输出:

$> 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

错误原因

这并非真的内存分配失败,而是错误处理逻辑不匹配:

  • backtrace.append()方法可能返回error.OutOfMemory错误
  • try关键字会将错误向上传递,但main()被声明为返回void,无法接收任何错误值,因此编译器抛出报错。

解决方案

有两种常见处理方式:

方式一:修改main函数返回类型为!void

让main函数可以向上传递错误,Zig的启动代码会自动处理顶层错误:

const std = @import("std");

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

pub fn main() !void { // 修改返回类型为!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)});
  }
}

方式二:用catch显式处理错误

如果不想修改main的返回类型,可以用catch捕获并处理OutOfMemory错误:

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});
    // 显式处理错误,示例用unreachable表示认为不会触发OOM
    backtrace.append(.{.node = n, .distance = @truncate(u8, d)}) catch unreachable;
    // 也可以自定义错误处理逻辑:
    // catch {
    //   std.debug.print("内存分配失败\n", .{});
    //   std.process.exit(1);
    // }
  }
}

内容的提问来源于stack exchange,提问作者sk3p7ic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:37:30