在 Delphi 函数中,结果经常被实现为 var 参数(尽管有 QC 票,但不是超出参数)。
字符串常量基本上是具有负 refcounter 的变量,应该抑制自动内存 [de] 分配。http://docwiki.embarcadero.com/RADStudio/XE3/en/Internal_Data_Formats#Long_String_Types
它确实抑制了它:下面的代码不会泄漏。
type
TDealRecord = record
id_Type: Integer;
Price: extended;
Remark: String;
end;
const const_loop = 100000000;
function TestVar: TDealRecord;
//procedure TestVar;
var
Li: Integer;
LRec: TDealRecord;
begin
for Li := 1 to const_loop do begin
FillChar(Lrec,SizeOf(LRec), 0);
LRec.Remark := 'Test';
// FillChar(Result,SizeOf(Result), 0);
// Result.Remark := 'Test';
end;
end;
但是改变操纵变量 - 它立即开始大量泄漏。
function TestVar: TDealRecord;
//procedure TestVar;
var
Li: Integer;
LRec: TDealRecord;
begin
for Li := 1 to const_loop do begin
// FillChar(Lrec,SizeOf(LRec), 0);
// LRec.Remark := 'Test';
FillChar(Result,SizeOf(Result), 0);
Result.Remark := 'Test';
end;
end;
事实证明,它string := const
是通过不同的调用实现的,具体取决于 LValue:
- 结果:AnsiString -> LStrAsg
- 结果:UnicodeString:-> UStrAsg
- 本地变量:UnicodeString:-> UStrLAsg
- 本地变量:AnsiString:-> LStrLAsg
虽然后两者按预期克隆指针,但前两者正在将字符串复制到新实例,就像我添加UniqueString
对它们的调用一样。
为什么会有这种差异?