Hi there!
I’m trying to make a HashMap
with values that are ArrayList
s, though the array lists have to be initialized dynamically in a loop.
I can’t really seem to get it to work, I think I don’t have a clear model of what is stored where yet in Zig and after trying for a while now I feel it is time to ask
Test 1:
const std = @import("std");
pub fn main() !void {
var allocator_type = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = allocator_type.allocator();
var data = std.AutoHashMap(usize, std.ArrayList(usize)).init(allocator);
defer {
var it = data.valueIterator();
while (it.next()) |val| {
val.deinit();
}
data.deinit();
}
for (0..10) |i| {
const idx = i % 2;
if (data.get(idx)) |list| {
try list.append(i);
} else {
var list = std.ArrayList(usize).init(allocator);
try list.append(i);
try data.put(idx, list);
}
}
var it = data.iterator();
while (it.next()) |entry| {
std.debug.print("{d}: {any}\n", .{entry.key_ptr.*, entry.value_ptr.*.items});
}
}
This was the first thing I thought to do, and I get error: expected type '*array_list.ArrayListAligned(usize,null)', found '*const array_list.ArrayListAligned(usize,null)'
from the call to append
. I’m not sure if I can easily make this work, but I didn’t manage at least.
Test 2:
const std = @import("std");
pub fn main() !void {
var allocator_type = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = allocator_type.allocator();
var data = std.AutoHashMap(usize, *std.ArrayList(usize)).init(allocator);
defer {
var it = data.valueIterator();
while (it.next()) |val| {
val.*.deinit();
allocator.destroy(val);
}
data.deinit();
}
for (0..10) |i| {
const idx = i % 2;
if (data.get(idx)) |*list| {
try list.*.append(i);
} else {
const ptr = try allocator.create(std.ArrayList(usize));
ptr.* = std.ArrayList(usize).init(allocator);
try ptr.*.append(i);
try data.put(idx, ptr);
}
}
var it = data.iterator();
while (it.next()) |entry| {
std.debug.print("{d}: {any}\n", .{entry.key_ptr.*, entry.value_ptr.*.items});
}
}
Trying to ensure that I have the pointers I want I tried this, and now it actually kind of works. I get the printout I want first, but after it crashes on the deallocation. But it also feels quite convoluted, and wanted to know if there was an easier way and how I should do the deallocation correctly if this is the way.