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

为何BobJenkinsHash函数在该场景下抛出范围检查错误?

解决FPC Lazarus中HashCode函数的Range Check Error问题

错误原因

RunError(201)是范围检查错误,触发的核心场景:

  • 当keyStr为空字符串时,keyStr[1]试图访问不存在的第一个字符,直接触发越界检查
  • 即使字符串非空,直接传递keyStr[1]作为哈希函数的首个参数,可能不符合BobJenkinsHash的参数类型预期,间接引发内存访问范围问题

修复方案

1. 优先处理空字符串场景

在调用哈希函数前先判断字符串是否为空,避免非法访问:

function MyClass.HashCode(): UInt32;
var
  keyStr: string;
begin
  keyStr := KeyToString();
  if keyStr = '' then
  begin
    Result := 0; // 空字符串返回固定哈希值,可根据业务需求调整
    Exit;
  end;
  // 正确传递字符串数据指针和长度
  Result := BobJenkinsHash(keyStr[1], Length(keyStr) * SizeOf(Char), 0);
end;

2. 规范指针传递方式

FPC中字符串为动态存储结构,直接传递数据指针更安全,避免空字符串时的直接字符访问:

function MyClass.HashCode(): UInt32;
var
  keyStr: string;
  dataPtr: Pointer;
  dataLen: Integer;
begin
  keyStr := KeyToString();
  if keyStr = '' then
  begin
    Result := 0;
    Exit;
  end;
  dataPtr := @keyStr[1];
  dataLen := Length(keyStr) * SizeOf(Char);
  Result := BobJenkinsHash(dataPtr^, dataLen, 0);
end;

3. 临时关闭局部范围检查(仅调试用)

如果只是临时排查问题,可在函数前后添加编译指令关闭范围检查,但这会隐藏其他潜在越界风险,不建议长期使用:

{$R-} // 关闭范围检查
function MyClass.HashCode(): UInt32;
{$R+} // 恢复范围检查
var
  keyStr: string;
begin
  keyStr := KeyToString();
  Result := BobJenkinsHash(keyStr[1], Length(keyStr) * SizeOf(Char), 0);
end;

额外注意事项

  • 测试空字符串、含特殊字符的字符串等边界场景,确保哈希计算逻辑覆盖所有情况
  • 确认KeyToString()的返回值可能为空,必须在哈希计算前做非空判断
  • 核对BobJenkinsHash的参数定义:首个参数应为无类型缓冲区或指针,直接传递字符值可能不符合函数预期

内容的提问来源于stack exchange,提问作者Adrian Maire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 19:02:39