Hi,
I never used a HashMap before, because my background is C and Fortran. So if I misunderstood anything here, please explain it to me. I want to create a HashMap where I have a set of keys (lets say they are of u8 type), and I want to store several values per key. If I’m not mistaken, this is not how hashmaps usually work. Usually one value per key, correct? Therefore I thought I would simply use an ArrayList as the value. they are resizable, thus I can append to them. Here is a test code I wrote:
const std = @import("std");
const KeyType = u8;
const Point = struct { x: usize, y: usize };
const ValueType = *std.ArrayList(Point);
const MapType = std.AutoHashMap(KeyType, ValueType);
fn addValueToKey(map: *MapType, key: KeyType, point: Point, allocator: std.mem.Allocator) !void {
const maybelist = map.get(key);
if (maybelist) |list| {
try list.append(point);
std.debug.print("oldlist {?}\n", .{list});
try map.put(key, list);
} else {
var newList = std.ArrayList(Point).init(allocator);
try newList.append(point);
std.debug.print("newlist {?}\n", .{newList});
try map.put(key, &newList);
}
}
fn getValuesForKey(map: *MapType, key: KeyType) ?ValueType {
return map.get(key) orelse null;
}
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var MyMap = MapType.init(allocator);
defer _ = MyMap.deinit();
try addValueToKey(&MyMap, 'a', Point{ .x = 1, .y = 2 }, allocator);
try addValueToKey(&MyMap, 'a', Point{ .x = 3, .y = 4 }, allocator);
try addValueToKey(&MyMap, 'b', Point{ .x = 5, .y = 6 }, allocator);
try addValueToKey(&MyMap, 'c', Point{ .x = 7, .y = 8 }, allocator);
std.debug.print("\n", .{});
const testkey: u8 = 'a';
if (MyMap.get(testkey)) |list| {
for (list.items, 0..) |item, idx| {
std.debug.print("{c} -> {d}: ({d},{d})\n", .{ testkey, idx, item.x, item.y });
}
} else {
std.debug.print("No values for key \"{c}\"\n", .{testkey});
}
}
In the function addValueToKey
I check if the key is already in the map. If yes, then get the value (a pointer to the array list) and append my new point. If not, just make a new array list and append the point and add the list to the map.
I know that I need to clean up the allocated memory at the end of the program. currently I am cleaning only map. However, long before that the GPA tells me that memory leaks, and sometimes I get a segfault. can someone tell me why? And how to fix it? Also I would appreciate if someone could tell me an easier way to store multiple values per key.
Thank you