首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有“指针”参数的方法在空闲Pascal中造成内存泄漏

带有“指针”参数的方法在空闲Pascal中造成内存泄漏
EN

Stack Overflow用户
提问于 2014-03-04 19:39:18
回答 3查看 1.6K关注 0票数 7

在将AnsiString的硬类型强制转换替换为TBytes (string数组)后(参见下面),Delphi报告了没有内存泄漏--但是,在TBytes值被传递给具有Pointer类型参数的方法时,TBytes显示了一个泄漏。

以下代码泄漏内存:

代码语言:javascript
复制
program project1;

{$mode delphi}

uses
  SysUtils;

function ToBytes(const AValue: AnsiString): TBytes;
begin
  SetLength(Result, Length(AValue)); // <-- leak (ine 10)
  if Length(AValue) > 0 then
    Move(AValue[1], Result[0], Length(AValue));
end;

procedure Send(P: Pointer);
begin

end;

begin
  Send(ToBytes('test'));

  SetHeapTraceOutput('heaptrace.log');
end. 

内存泄漏报告:

代码语言:javascript
复制
Call trace for block $001C5CC0 size 12   $00401586  TOBYTES,  line 10
of project1.lpr   $00401622  main,  line 21 of project1.lpr

如果我更改Send方法以接受TBytes类型的参数,内存泄漏就会消失。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-04 19:44:23

那是编译器的错误。托管类型TBytes具有引用计数生存期。编译器应该创建一个隐式局部变量,该变量分配给ToBytes返回的数组。您需要通过存储到一个显式的本地来解决这个问题:

代码语言:javascript
复制
var
  Tmp: TBytes;
....
Tmp := ToBytes(...);
Send(Tmp);
票数 4
EN

Stack Overflow用户

发布于 2014-03-05 13:38:07

它可能不是你所认为的错误。FPC的堆跟踪已经知道了跟踪主程序(主.dpr begin..end)中的温度(以及一般的自动类型)的问题。

将代码移动到一个过程中,并从主begin..end调用它。你就会发现泄漏消失了。

这是因为主程序的一般结构如下

代码语言:javascript
复制
begin 
  initializeunits(); // procedure call inserted by the compiler
    <actual mainprogram statements>
  finalizeunits();   // procedure call inserted by the compiler
end.

随着主程序温度的发布发生在“结束”。在最终确定的单位,最终堆跟踪。(即使是第一个单位,它仍然只是一个单位)。所以heaptrc想念这个。

票数 1
EN

Stack Overflow用户

发布于 2014-03-04 21:04:57

返回可能包含大量内存的东西的函数使我感到局促不安。这可能只是一种感觉或个人偏好,但它确实剥夺了对记忆分配的控制。对于返回(新构造的) TStringList实例的函数,也有类似的说法,也建议传递指向TStrings对象的指针,并让调用方控制对象的生命周期。

在这里,我建议对TBytes上的所有操作使用var参数,并强制调用方提供要处理的实例。如果您构建了一个复杂的应用程序,而必须搜索可以提高性能的地方,请再次考虑这一点,看看是否可以回收具有类似内容或长度的TBytes实例。Delphi string系统的一个重要特性是在幕后为您进行引用计数和复制,在应用程序处理大量(类似的)字符串时提供这种性能增益。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22181340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档