【问题标题】:getmem memory leak, delphigetmem内存泄漏,delphi
【发布时间】:2010-01-18 18:22:49
【问题描述】:

我正在尝试在 Delphi 中运行一个旧的 midi 组件,它大部分都可以工作,但是如果我尝试连续加载 2 个文件,它会崩溃。

一些研究让我安装了 EurekaLog,这表明代码中存在内存泄漏。耶!

我对内存指针的东西不是很好,但是这段代码被 Eureka 突出显示在这里让我思考,也许有一个内存没有被释放的错误??

我尝试在末尾添加FreeMem,但它不起作用?

function TMidifile.ReadString(F: integer): string;
var
  s: PChar;
  i: integer;
begin
  GetMem(s, F + 1);
  s[F] := chr(0);
  for i := 0 to F - 1 do
  begin
    s[i] := Chr(chunkIndex^);
    inc(chunkIndex);
  end;
  result := string(s);
end;

【问题讨论】:

  • 首先,调用 FreeMem 后“它不起作用”是什么意思?二、你用的是什么版本的Delphi?

标签: delphi memory-leaks


【解决方案1】:

Kornel 的想法是正确的。您可能可以进一步简化它,如下所示:

function TMidifile.ReadString(F: integer): AnsiString; 
begin
  SetLength(Result, F);
  Move(ChunkIndex^, result[1], F);
  inc(chuncIndex, F);
end;

这将使阅读速度更快,特别是如果您使用的是 Move 的 Fastcode 版本(或带有内置于 RTL 中的 Fastcode 版本的最新版本的 Delphi。)

【讨论】:

  • +1: 我不敢用move 的方式,因为我没有方便的编译器来测试它;>
  • @Mason:小心,因为 Dom 可能使用的是 Delphi 2009 或更高版本,然后 Move 会移动字节,而不是字符。
  • 尝试了您的例程,但由于某些原因,它产生了 Range CCheck 错误。但是感谢您的努力。
  • 在哪一行?我能想到的唯一会产生范围检查错误的方法是在第二行(移动),如果 F = 0。如果是这种情况,然后在函数顶部添加 if F = 0 then result := '' else ...,它应该采取照顾它。
  • 是的,我相信这也是一个 F = 0 的问题。我在尝试使用 i= 0 到 F 的另一个例程时遇到了同样的错误,但是 i:= 1 到 F 是可以的。谢谢!
【解决方案2】:

您不能将类型转换为 AnsiString,因为它们是引用计数的。

这不是更容易吗?

function TMidifile.ReadString(F: integer): string; 
var i: integer; 
begin
  SetLength(Result, F);  
  for i := 1 to F do 
  begin 
    Result[i] := Chr(chunkIndex^); 
    inc(chunkIndex); 
  end; 
end;

【讨论】:

  • 这似乎解决了这个问题!我不再收到内存泄漏的警告了 :) 感谢神奇的修复! 正在进行测试
  • @Dom:太好了!很高兴它有帮助:)
  • 我从来没有教过这么小部分的代码可以修复它!我很惊讶
【解决方案3】:

问题是您不能将一堆随机字节转换为stringstring 具有特定的结构,分配由编译器管理。

我可以为你重写这段代码,但我认为我不会对你有任何帮助,因为我必须假设调用它的代码在内存管理方面并没有做得更好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    相关资源
    最近更新 更多