I want to pass a texture path to a C function:
fn addSentinelToStr(allocator: std.mem.Allocator, str: []u8) ![:0]u8 {
const buf = try allocator.allocSentinel(u8, str.len, 0);
@memcpy(buf, str);
return buf;
}
fn joinPathSentinel(allocator: std.mem.Allocator, paths: []const []const u8) ![]u8 {
const joined = try std.fs.path.join(allocator, paths);
//defer allocator.free(joined);
//return (try addSentinelToStr(allocator, joined));
const res = try addSentinelToStr(allocator, joined);
allocator.free(joined);
return (res);
}
main () {
[...]
var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .init;
const allocator = general_purpose_allocator.allocator();
const current_exe_dir: []u8 = try std.fs.selfExeDirPathAlloc(allocator);
defer allocator.free(current_exe_dir);
const texture_path = try joinPathSentinel(allocator, &.{current_exe_dir, "textures/container.jpg"});
defer allocator.free(texture_path);
[...]
}
It seems to me like I free everything correctly, but this is what I get:
error(gpa): Allocation size 89 bytes does not match free size 88. Allocation:
...\triangle.zig:53:44: 0x922337 in addSentinelToStr (triangle.exe.obj)
const buf = try allocator.allocSentinel(u8, str.len, 0);
^
...\triangle.zig:62:37: 0x923efe in joinPathSentinel (triangle.exe.obj)
const res = try addSentinelToStr(allocator, joined);
^
...\triangle.zig:459:46: 0x925ef5 in main (triangle.exe.obj)
const texture_path = try joinPathSentinel(allocator, &.{current_exe_dir, "textures/container.jpg"});
^
...\lib\std\start.zig:590:75: 0x92901a in main (triangle.exe.obj)
return callMainWithArgs(@as(usize, @intCast(c_argc)), @as([*][*:0]u8, @ptrCast(c_argv)), envp);
^
...\lib\libc\mingw\crt\crtexe.c:267:0: 0x9c0b70 in __tmainCRTStartup (crt2.obj)
mainret = _tmain (argc, argv, envp);
Would someone know how I lose that 1 byte? I suspect it’s the sentinel? But why?