使用FastMM4可以轻松注册泄漏的指针,但不能注册泄漏的字符串。显然,应用于字符串的@
运算符并没有真正为我们提供整个字符串,PChar(string)
也没有;我可以使用什么来很好地注册泄漏的字符串?
现在我发现这有效:
FastMM4.RegisterExpectedMemoryLeak(Pointer(NativeInt(PChar(StringVariable))-12));
但它依赖于幻数12
,这是与版本相关的,并且代码实际上并没有表达正在发生的事情。我希望某处有一个 RTL 函数,它接受一个字符串并返回指向字符串"基"的指针,或者一些我忽略FastMM4
方法。
我可以在这样的程序中包装那个丑陋的表情野兽,但我仍然觉得它很笨拙:
procedure RegisterExpectedStringLeak(const s:string);
begin
{$IFDEF VER210}
FastMM4.RegisterExpectedMemoryLeak(Pointer(NativeInt(PChar(s))-12));
{$ELSE}
{$MESSAGE Fatal 'This only works on Delphi 2010'}
{$ENDIF}
end;
这应该与问题无关。这就是我泄漏字符串的原因:
我正在使用缓存机制在应用程序的生命周期内存储某些数据片段。我不打算释放这些对象,因为我确实在应用程序的生命周期内需要它们,并且在应用程序关闭时进行适当的完成只会花费腰部时间。这些对象包含一些字符串字段,因此显然这些字符串被"泄漏"了。
我能想到的最接近的是:
function RegisterExpectedStringLeak(const S: string): Boolean;
type
{Have to redeclare StrRec here, because it is not in the interface section of system.pas}
PStrRec = ^StrRec;
StrRec = packed record
{$ifdef CONDITIONALEXPRESSIONS}
{$if RTLVersion >= 20}
codePage: Word;
elemSize: Word;
{$ifend}
{$endif}
refCnt: Longint;
length: Longint;
end;
begin
Result := RegisterExpectedMemoryLeak(Pointer(NativeInt(PChar(S)) - SizeOf(StrRec)));
end;
StrRec
的重新声明是从德尔福XE的getmem.inc
(FastMM4)复制的-我只添加了{$ifdef CONDITIONALEXPRESSIONS}
.我认为它也应该向后兼容旧版本的Delphi。