在VCL中,TByteDynArray被定义为动态数组:
type TByteDynArray = array of Byte;
Run Code Online (Sandbox Code Playgroud)
但似乎没有完成索引边界检查:
var
DataBytes: System.Types.TByteDynArray;
i: Integer;
begin
SetLength(DataBytes, 2);
DataBytes[5] := 222; // Accessing index beyond set length.
i := DataBytes[5]; // `i` is now set to "222".
Run Code Online (Sandbox Code Playgroud)
上面的代码运行没有错误.
为什么AccessViolation不像一个静态数组一样被提升?什么是点SetLength,如果你可以访问和修改65536个字节数组变量的内存,无论长度设定的?
要检测数组索引超出范围错误,请设置范围检查错误.
$ R指令启用或禁用范围检查代码的生成.在{$ R +}状态中,所有数组和字符串索引表达式都被验证为在定义的范围内,并且所有对标量和子范围变量的赋值都被检查在范围内.如果范围检查失败,则引发ERangeError异常(或者如果未启用异常处理,则终止程序).
这默认设置为{$ R-},但我建议将其设置为开启,至少在开发阶段.它为代码增加了额外的开销,因此这可能是它默认关闭的原因.
如果您的设备经过良好测试并希望避免范围检查,请在设备顶部添加{$ R-}.这将在本地覆盖项目设置.
如果要避免代码块中的范围检查,可以使用以下技术:
{$IFOPT R+}
{$DEFINE RestoreRangeCheck}
{$R-}
{$ENDIF}
{- Some code here }
{$IFDEF RestoreRangeCheck}
{$R+}
{$UNDEF RestoreRangeCheck}
{$ENDIF}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
557 次 |
| 最近记录: |