范围检查错误和Delphi 7.0

5
经过一周对我的程序进行FastMM4内存泄漏检查和修复后,我最终在另一台电脑上测试了我的程序。现在,我遇到了“范围检查错误”问题。我已经在网上研究了好几个小时,但是没有一个答案能够解决我的问题。我的程序编译时启用了运行时错误选项“范围检查”。因此,我知道这就是为什么出现错误的原因,但我需要确切地知道引发错误的原因。
该程序是在XP上使用Delphi 7.0编译的,测试PC是Windows 7。一旦它启动,我的程序就开始通过串口通信,然后出现“范围检查错误”消息框。当我停止串口通信时,就不会再出现“范围检查错误”框。这意味着什么,我该如何解决它?我正在寻找简单的解决策略,因为我知道我可能要花数天时间逐行检查代码。
“范围检查错误”是由于值的分配不当或访问数组的不可访问索引引起的,我的理解正确吗?

1
你能在另一台机器上安装Delphi并进行调试吗? - Blorgbeard
更好的做法是,我考虑通过注释掉代码段并重新编译来缩小到有问题的代码行。然后,在 Window 7 PC 上运行测试程序。我知道这将是繁琐的,但我认为我知道程序的哪个部分出了问题。 - ThN
为什么你不按照我的建议,在映射文件中找出有问题的那一行呢? - David Heffernan
1
在这里查看有关范围检查的更多信息:https://dev59.com/0GLVa4cB1Zd3GeqPyaQi#75578536 - Gabriel
2个回答

8
您对范围检查错误的理解是正确的。当您访问数组超出其界限时,它们就会出现。例如:
type
  TFixedArray = array [0..41] of Integer;
var
  a: TFixedArray;
begin
  a[42] := 1+2;//!! this is a range check error !!
end;

或者对于一个动态数组:
var
  a: array of Integer;
begin
  SetLength(a, 666);
  a[665] := 12;//this is fine
  a[666] := 42;//!! this is a range check error !!
end;

我已经用赋值操作来举例,但是如果使用超出范围的索引读取数组也会产生范围错误。
范围错误应该报告其发生的地址,然后您可以使用映射文件将其转换为代码位置。如果您使用madExcept或类似工具,效果会更好。

更新

在Ken的提示下,文档说明了范围检查选项所影响的内容如下:

在{$R+}状态下,所有数组和字符串索引表达式都将被验证是否在定义的边界内,并且对标量和子范围变量的所有赋值都将进行范围检查。


仅作补充:在{$R+}状态下,所有数组和字符串索引表达式都会被验证是否在定义的范围内,并且所有对标量和子范围变量的赋值都会被检查是否在范围内。注意字符串索引标量和子范围变量 - Ken White
你的例子非常棒,但是你一定要用“666”吗?哈哈。 - ThN
@digitalanalog - 为什么不呢,这样你会更好地记住它 :) - user532231
范围检查错误会导致内存泄漏吗?由于当您在运行时错误下不检查“范围检查”时,该错误被抑制,因此我确定该错误仍然会被引发,但不会显示在消息框中。 - ThN
@digitalanalog 访问数组越界可能会导致你能想到的任何故障模式!一旦你开始随意操作内存位,所有的赌注都是无效的。 - David Heffernan
已经找到了错误。我的字符串解析器在if条件块中检查字符串变量中的每个字符和字符串的长度,因此引发了区间错误检查。现在它运行得很好...下次再见,谢谢。 - ThN

1
阅读了有关“范围检查错误”概念的其他信息后,我认为在这种情况下导致“范围检查错误”的原因是:分配给程序读取的串口访问的变量是一个16字节(或更小)类型,并且程序读取的串口超出了变量的限制。 请注意[当我停止串行通信时,就没有“范围检查错误”框。],这应该说明所有事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接