I usually follow the init() and create(allocator) idiomatic ways of creating structs, but this time I’m confused about how a field of a heap-allocated struct that’s also a struct should be initialized.
I came up with a setup() function that basically initializes the struct in place because I’m not sure if the allocation will first happen in the stack then copied to the actual place in the heap, for larger buffers that’d cause a stack-overflow.
But this feels wrong (?) in a way that, if I end up forgetting to call it I’d be generating undefined-behavior down at the functions accessing the field.
const LOGGER_BUF_SIZE = 1024 * 8;
const LoggerContext = struct {
writer: Writer,
instance: Logger,
buffer: [LOGGER_BUF_SIZE]u8,
fn setup(self: *LoggerContext) void {
self.writer = std.fs.File.stdout().writer(&self.buffer);
self.instance = .init(self.writer.interface, .Debug);
}
};
pub const Application = struct {
const Self = @This();
allocator: Allocator,
logger: LoggerContext,
// TODO: accept different sinks as argument
pub fn create(allocator: Allocator) !*Self {
const ptr = try allocator.create(Self);
ptr.* = .{
.allocator = allocator,
.logger = .{ .buffer = undefined, .writer = undefined, .instance = undefined },
};
ptr.logger.setup();
return ptr;
}
pub fn deinit(self: *Self) void {
self.allocator.destroy(self);
}
};