在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
相关产品推荐
相关产品推荐

