diff options
author | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-05 12:16:50 +0100 |
---|---|---|
committer | Baitinq <manuelpalenzuelamerino@gmail.com> | 2025-01-05 12:17:36 +0100 |
commit | 40b9ca0fdd1283f328ad26f1276259526d2cd861 (patch) | |
tree | 961919202a0639dc75ba77bf3588653cf6e7e4a4 | |
parent | clean (diff) | |
download | c-hashtable-40b9ca0fdd1283f328ad26f1276259526d2cd861.tar.gz c-hashtable-40b9ca0fdd1283f328ad26f1276259526d2cd861.tar.bz2 c-hashtable-40b9ca0fdd1283f328ad26f1276259526d2cd861.zip |
fix memory bug in hashmap implementation
-rw-r--r-- | lib/hashtable.c | 4 | ||||
-rw-r--r-- | src/main.zig | 39 |
2 files changed, 16 insertions, 27 deletions
diff --git a/lib/hashtable.c b/lib/hashtable.c index f9f9873..98d9805 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -79,12 +79,12 @@ int hashtable_put(HashTable ht, char* key, void* val, size_t val_size) { int index = hash(key, ht_impl->capacity); HashTableBucket* bucket = &ht_impl->buckets[index]; - //TODO: reuse the deleted? for (int i = 0; i < bucket->length; ++i) { HashTableData* data = &bucket->data[i]; if (strcmp(data->key, key) == 0) { - data->data = val; + data->data = realloc(data->data, val_size); + memcpy(data->data, val, val_size); data->deleted = 0; return 0; } diff --git a/src/main.zig b/src/main.zig index bf600df..5ad6dd3 100644 --- a/src/main.zig +++ b/src/main.zig @@ -42,7 +42,6 @@ test "removing element" { try std.testing.expectEqual(null, res); } -const allocator = std.heap.page_allocator; test "fuzzing" { try std.testing.fuzz(struct { pub fn func(source: []const u8) !void { @@ -51,42 +50,32 @@ test "fuzzing" { var ht = hashtable.hashtable_init(capacity); defer _ = hashtable.hashtable_deinit(&ht); - std.debug.print("START!\n", .{}); - - var reference_hashmap = std.AutoHashMap([*c]u8, *u8).init(allocator); //TODO: testing allocator + // NOTE: BufMap doesnt require memory management + var reference_hashmap = std.BufMap.init(std.testing.allocator); + defer reference_hashmap.deinit(); var i: usize = 1; while (i + 2 < source.len) : (i += 2) { const operation: u8 = source[i]; const key: [*c]u8 = @constCast(@as([2]u8, .{ source[i + 1], 0 })[0..]); - const value: u8 = source[i + 2]; - - // std.debug.print("Key: ptr {any} - value {d}\n", .{ key, key.* }); + const value: [*c]u8 = @constCast(@as([2]u8, .{ source[i + 2], 0 })[0..]); - switch (operation % 3) { + switch (operation % 2) { 0 => { - std.debug.print("Getting key {any}\n", .{key}); - const ret: ?*u8 = @ptrCast(hashtable.hashtable_get(ht, key)); - const reference_ret: ?*u8 = reference_hashmap.get(key); - // std.debug.print("Reference get value: {any}\n", .{reference_ret}); - try std.testing.expectEqual(reference_ret, ret); + const ret: ?[*]u8 = @ptrCast(hashtable.hashtable_get(ht, key)); + const reference_ret: ?[]const u8 = reference_hashmap.get(key[0..2]); + if (ret == null or reference_ret == null) { + try std.testing.expectEqual(ret == null, reference_ret == null); + } else { + try std.testing.expectEqualStrings(reference_ret.?, @as([*]u8, ret.?)[0..2]); + } }, 1 => { - std.debug.print("Putting key {any} - {d}\n", .{ key, key.* }); - _ = hashtable.hashtable_put(ht, key, @constCast(&value), @sizeOf(u8)); - try reference_hashmap.put(key, @constCast(&value)); - }, - 2 => { - std.debug.print("Removing key {any} - {d}\n", .{ key, key.* }); - const ret = hashtable.hashtable_remove(ht, key); - const reference_ret = reference_hashmap.remove(key); - const a: i32 = if (reference_ret) 1 else 0; - try std.testing.expectEqual(a, ret); + _ = hashtable.hashtable_put(ht, key, @constCast(value), @sizeOf(u8) * 2); + try reference_hashmap.put(key[0..2], @as([*]u8, value)[0..2]); }, else => unreachable, } - //we cannot free or it will reuse the same memory and also doesnt make sense - // allocator.free(rawkey); } } }.func, .{}); |