Zig v0.11.0中std.mem.indexOfDiff疑似损坏切片的问题排查
Zig v0.11.0中std.mem.indexOfDiff引发切片异常问题排查
原本在Zig v0.10.x中运行正常的代码,升级至v0.11.0后出现异常:调用std.mem.indexOfDiff后,原本正确的切片bcd被损坏,导致后续的相等性检查失败。
相关代码
主逻辑代码
const packet = [_]u8{ 0x17, 0x20, 0x00, 0x00, 0x78, 0x37, 0x2a, 0x18, 0x4e, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x01, .... }; const offset = 20; const bcd: []const u8 = try bcd2string(packet[offset..][0..7]); const expected: []const u8 = "20220823094706"; std.debug.print(">>> BCD: {any}\n", .{ bcd }); std.debug.print(">>> expected: {any}\n", .{ expected }); std.debug.print(">>> eql(before): {any}\n", .{ std.mem.eql(u8, expected,bcd) }); if (std.mem.indexOfDiff(u8, bcd, expected)) |index| { std.debug.print(">>> indexOfDiff: {any} {any} {any}\n", .{ expected, bcd, index }); } std.debug.print(">>> eql(after): {any}\n", .{ std.mem.eql(u8, expected,bcd) });
bcd2string函数
fn bcd2string(slice: []const u8) ![]const u8 { var buffer: [64:0]u8 = undefined; return try std.fmt.bufPrint(&buffer, "{s}", .{ std.fmt.fmtSliceHexLower(slice)}); }
运行输出
>>> BCD: { 50, 48, 50, 50, 48, 56, 50, 51, 48, 57, 52, 55, 48, 54 } >>> expected: { 50, 48, 50, 50, 48, 56, 50, 51, 48, 57, 52, 55, 48, 54 } >>> eql(before): true >>> indexOfDiff: { 50, 48, 50, 50, 48, 56, 50, 51, 48, 57, 52, 55, 48, 54 } { 136, 252, 94, 228, 254, 127, 0, 0, 136, 252, 94, 228, 254, 127 } 0 >>> eql(after): false
问题分析
问题出在bcd2string函数的格式化逻辑中:
std.fmt.fmtSliceHexLower(slice)返回的是HexLower结构体,它实现了fmt.Formatter接口,需要通过{}格式符触发正确的格式化逻辑。- 代码错误使用
{s}格式符,该格式符期望接收字符串切片([]const u8),但实际传入的是HexLower结构体。这会导致Zig直接读取结构体内存内容当作字符串切片处理,属于未定义行为。 - 在Zig v0.10.x中,结构体内存布局可能碰巧让临时数据指针被正确读取,代码能正常工作;但v0.11.0对内存生命周期和类型检查的处理更严格,后续访问
bcd时临时内存已被覆盖,std.mem.indexOfDiff的调用进一步触发内存内容变化,表现为切片损坏。
解决方案
修改bcd2string函数中的格式化字符串,将"{s}"改为"{}",让HexLower结构体的格式化逻辑正确执行:
fn bcd2string(slice: []const u8) ![]const u8 { var buffer: [64:0]u8 = undefined; return try std.fmt.bufPrint(&buffer, "{}", .{ std.fmt.fmtSliceHexLower(slice)}); }
修改后,bufPrint会正确调用fmtSliceHexLower的格式化方法,生成符合预期的十六进制字符串,后续std.mem.indexOfDiff调用不会再出现切片损坏问题,相等性检查会始终返回true。
内容的提问来源于stack exchange,提问作者tonys
相关产品推荐
相关产品推荐

