Delphi内存泄漏,指向TStringList

时间:2016-10-27 12:51:05

标签: delphi pointers memory-leaks

我在理解指针的行为方面遇到了一些麻烦。 我有一个非常简单的例子来证明:

type
  PSL = ^TStringList;
...
var
  myPSL : PSL;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  New(myPSL);
  myPSL^ := TStringList.Create;
  myPSL^.Add('String 1');
  myPSL^.Add('String 2');
  myPSL^.Add('String 3');
end;
...
procedure TForm1.FormDestroy(Sender: TObject);
begin
  Dispose(myPSL);
end;

使用此代码我得到此内存泄漏报告

29 - 36 bytes: UnicodeString x 3
37 - 44 bytes: Unknown x 1
85 - 92 bytes: TStringList x 1

现在,如果我打电话

myPSL^.Free;
在处理指针之前

,然后没有报告任何内容。

我无法理解为什么会这样。我知道调用 New()分配足够的内存(基于指针的类型)并调用 Dispose()负责释放相同的内存,那为什么我需要免费指针,好像它是一个“真正的”对象?

谢谢!

2 个答案:

答案 0 :(得分:12)

类对象已被指针引用。定义指向引用类型的指针毫无意义。只需直接使用该类型:

var
  myPSL : TStringList;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  myPSL := TStringList.Create;
  myPSL.Add('String 1');
  myPSL.Add('String 2');
  myPSL.Add('String 3');
end;
...
procedure TForm1.FormDestroy(Sender: TObject);
begin
  myPSL.Free;
end;

您的代码实际执行的操作如下:

New(myPSL)Dispose(myPSL)只是分配/解除分配大小为sizeof(TStringList)字节的内存块,但实际上并没有构造/破坏该内存中的TStringList对象。您需要致电myPSL := TStringList.CreatemyPSL.Free

答案 1 :(得分:5)

您不需要存储指向TStringList的指针,TStringList的实例实际上也是指针。要解决此问题,请将myPSL的类型更改为以下内容:

var
   myPSL : TStringList;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  myPSL := TStringList.Create;
  myPSL.Add('String 1');
  myPSL.Add('String 2');
  myPSL.Add('String 3');
end;
...
procedure TForm1.FormDestroy(Sender: TObject);
begin
  myPSL.Free;
end;

如果以某种方式,您仍需要使用旧代码,以避免内存泄漏,则需要在部署Free之前致电myPSL

myPSL^.Free;
dispose(myPSL);