ETL exercise on Zig track leaks memory in tests

I reduced my solution to return Error.OutOfMemory just to fun:

pub fn transform(
    _: std.mem.Allocator,
    _: PointsToLettersMap,
) Error!LetterToPointsMap {
    return Error.OutOfMemory;
}

And I got a funny message about a bunch of failed tests and a memory leak. I expected the tests to fail but I did not expect them to leak memory.

The offending line in every test is:

legacy.deinit();

It frees memory only on the happy path. actual.deinit() is similarly misplaced, but I did not care to trigger the memory leak there. We should use defer or errdefer to ensure that memory is freed even if there is an error:

test "single letter" {
    var legacy = std.AutoHashMap(i5, []const u8).init(testing.allocator);
    defer legacy.deinit(); // here
    try legacy.put(1, "A");
    var actual = try transform(testing.allocator, legacy);
    defer actual.deinit(); // and also here

    try testing.expectEqual(1, actual.count());
    try testing.expectEqual(1, actual.get('a'));
}
1 Like

Fixing in PR 583

1 Like