Delphi字符串不可靠

时间:2016-02-27 06:30:22

标签: string delphi pascal

Hello im目前正在创建一个非常繁重的应用程序,它可以在另一个应用程序线程上进行中继并抓取句柄。因此,如果该应用程序会冻结,那么我的应用程序会在目标软件负载很重的情况下不时出现滞后现象。

问题在于,如果某种程度上更重的应用程序“滞后”我会遇到字符串的意外问题,并且它们会给我不可靠的输出。

任何人都知道为什么会这样,以及我如何解决这个问题或解决这个问题?

我目前正在使用的解决方案是belove,但这并不是我想要做的事情,因为它确实使得运行时非常不可靠,因为我无法确定结果。

function GetInt(MyNum:string):integer;
begin
  try
    result := strtoint(MyNum);
  except
    result := 0;
  end;
end;

作为一个例子,我制作了这个脚本,突然我得到了$ ReBEFF不是一个有效的整数。 (突然间,它已经运行好几个小时了)

oldB是一个Byte,它作为转换为十六进制的数字处理。 oldB设置为始终为0,它应该永远不会更改,尤其是对于甚至不在十六进制数字系统内的Re

xx0000 = B
00xx00 = G
0000xx = R

示例脚本(这不是唯一一个遇到字符串问题的代码部分,它无缘无故地随机出现在应用程序中)

var
  oldR:byte = 0;
  oldG:byte = 30;
  oldB:byte = 0;
  _Down:bool = false;

function GetColor(R, G, B:byte):integer;
var
  MyColor:string;
begin
  MyColor := '';
  MyColor := MyColor + inttohex(B, 2);
  MyColor := MyColor + inttohex(G, 2);
  MyColor := MyColor + inttohex(R, 2);
  result := strtoint('$' + MyColor);
end;

procedure TMainF.DonateColorTimer(Sender: TObject);
var
  MyColor:integer;
begin

  oldR := 255;

  if _Down then begin
    dec(oldG, 10);
    if oldG <= 0+30 then
      _Down := false;
  end else begin
    inc(oldG, 10);
    if oldG >= 255-30 then
      _down := true;
  end;

  oldB := 0;

  MyColor := GetColor(oldR, oldG, oldB);

  if MyColor = 0 then
    exit;

  Label32.Font.Color := MyColor;
  Label33.Font.Color := MyColor;
end;

当我强调我的应用程序时,我确实设法在应用程序的代码部分中获取访问错误FFFFFFFC(数组中的-1?),该结构本身不在我的代码部分中(代码部分甚至在我的GUI之前运行)是在我重新运行应用程序并使用调试器进行测试时创建的)遗憾的是我无法重复找到它。

然而,感觉某些来自“delphi中的库”的函数无法处理“滞后”并且它自身重叠并使字符串变得混乱。

我正在使用RAD Studio XE 8

另一个突然得到消息的例子

function GetAppPath:string;
var
  Buffer: Array[0..260] of Char;
  Path:string;
begin
  try
    GetModuleFileName(hInstance, Buffer, Length(Buffer));
    Path := ExtractFilePath(Buffer);
    result := Path;
  except
  end;
end;

Should have returned D:\Download\Finished\Apps\
returned D:\Download\Finished\A#ps\

1 个答案:

答案 0 :(得分:13)

由于代码中存在缺陷,您描述的症状是内存损坏。您正在调用的库函数没有可能产生这些症状的已知缺陷。概率接近1时,代码中存在缺陷。

具有这些症状的常见缺陷是在释放后写入内存。如果内存管理器重新使用释放的内存进行新分配,则会观察到此类症状。

您需要做更多事实查找调试以确定缺陷的来源。完全调试模式下的FastMM将是开始调查的好工具。但您可能需要的不仅仅是工具。

如果您错过了我的观点,请让我说清楚。所有证据都表明您的代码中存在缺陷。

现在,我们可以看到对代码的一些具体评论:

我担心您似乎已经在代码中的多个位置放置了吞下所有异常处理。作为一般规则,您不应该处理异常。您应该让异常在调用堆栈中传播。首先删除所有这些吞下所有异常处理程序。

您对Windows API GetModuleFileName的调用忽略了返回值。 Windows API函数不会引发异常,而是通常通过返回值指示成功或失败。请参阅您调用的所有Windows API函数的文档。

您对全局变量的使用相当令人担忧。我们可以看到的那些全局变量应该是TMainF的字段。也许你有其他全局因素导致问题。

您应该为控件提供有意义的名称。 Label32对代码的读者没有任何意义,通常是你。不要让IDE编写代码。

应该使用按位运算将颜色通道值转换为RGB值。没有任何地方可以进行文字转换。

Color := B shl 16 or G shl 8 or R;