I'm trying to build a slice of slices using multiple std.ArrayList
s.
The code below works, but the memory allocator std.testing.allocator
warns me of a memory leaks wherever I append new elements to a sublist
.
const std = @import("std");
const mem = std.mem;
fn sliceOfSlices(allocator: *mem.Allocator) ![][]usize {
var list = std.ArrayList([]usize).init(allocator);
var i: usize = 0;
while (i < 3) : (i += 1) {
var sublist = std.ArrayList(usize).init(allocator);
// errdefer sublist.deinit(); // here?
var n: usize = 0;
while (n < 5) : (n += 1) {
try sublist.append(n); // leaks
// errdefer sublist.deinit(); // here?
// errdefer allocator.free(sublist.items);
}
try list.append(sublist.toOwnedSlice());
}
return list.toOwnedSlice();
}
const testing = std.testing;
test "memory leaks" {
const slice = try sliceOfSlices(testing.allocator);
testing.expectEqual(@intCast(usize, 3), slice.len);
testing.expectEqual(@intCast(usize, 5), slice[0].len);
}
I tried to use errdefer
in several places to free the allocated sublist
, but it didn't work. From the documentation it seems a lifetime issue, but I'm not sure how to handle it.
the std.ArrayList(T).items slice has a lifetime that remains valid until the next time the list is resized, such as by appending new elements. — https://ziglang.org/documentation/master/#Lifetime-and-Ownership
What's the appropriate error handling when list.append()
fails?