#panic: incorrect alignment or segfault, while iterating on an AutoHashMapUnmanaged

1 messages · Page 1 of 1 (latest)

summer lotus
#

I have a hashmap from u32 to some union. I have a "minimal" example bellow (the binary is not exactly master but close enough, and I haven't seen anything about this in the issues.)

const std = @import("std");
const mem = @import("std").mem;

const ValueRef = u32;
const BlockRef = u32;

pub const ValuePool = struct {
    values: ValueMap = .{},
    value_counter: ValueRef = 0,

    const ValueMap = std.AutoHashMapUnmanaged(ValueRef, ValueData);

    pub fn deinit(self: *ValuePool, allocator: mem.Allocator) void {
        self.values.deinit(allocator);
    }

    pub fn put(self: *ValuePool, allocator: mem.Allocator, value: ValueData) mem.Allocator.Error!void {
        try self.values.put(allocator, self.value_counter, value);
    }

    pub fn iterator(self: ValuePool) ValueMap.Iterator {
        return self.values.iterator();
    }
};

pub const Block = struct {
    values: ValuePool = .{},

    pub fn deinit(self: *Block, allocator: mem.Allocator) void {
        self.values.deinit(allocator);
    }

    pub fn formata(self: Block) !void {
        var iter = self.values.iterator();
        while (iter.next()) |kv| {
            std.debug.assert(@tagName(kv.value_ptr.*).len > 0); // if I remove this line, it still segfaults
        }
    }
};

pub const formatter = struct {
    block: Block = .{},

    pub fn format(
        self: formatter,
        comptime _: []const u8,
        _: std.fmt.FormatOptions,
        _: anytype,
    ) !void {
        try self.block.formata();
    }
};

pub const ValueData = union(enum) {
    param: struct { idx: usize },
    inst: i32,
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    var allocator = gpa.allocator();

    var f = formatter{};
    defer f.block.deinit(allocator);

    _ = try f.block.values.put(
        allocator,
        ValueData{ .param = .{ .idx = 0 } },
    );

    std.log.info("{}", .{f});
}```
#

now if Block contains the ValueMap it's all good, it only happens when it's in a separate structure

#

when it's in my actual code, it outputs this:

            return @ptrCast(@as([*]Header, @ptrCast(@alignCast(self.metadata.?))) - 1);```
or sometimes segfaults on the same thing (accessing the structure), but also, when debugging with gdb, the union data is nonsense
meager fog
#

change pub fn iterator(self: ValuePool) to pub fn iterator(self: *const ValuePool)

#

the iterator points at the hash map

#

you're making it point at a copy of it that lives in the parameter stack, which is popped off when the function returns

summer lotus
#

huh
so when I do self: ValuePool it creates a copy?

#

always? I've read like a few years ago it decides whether or not to put it on the stack based on something else idk

meager fog
#

there's no guarantee of whether it will or won't

#

but semantically speaking, it's always a copy

#

so if you need a reference, you should take an explicit reference

summer lotus
#

Or does it do some deep clone (doesn't make sense to me)

#

So I'm missing something

meager fog
summer lotus
#

Ah ok

meager fog
#

The function call makes a copy of the hash map

#

Erego, problemas

summer lotus
#

Yea sure