You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:17:03