Delphi中使用指向TStringList的指针出现内存泄漏问题

4

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

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()会负责释放该内存,那么为什么需要像“真实”对象一样Free指针呢?

谢谢!


1
你最开始是在跟随哪个教程,才会陷入这种困境呢? - Rob Kennedy
2个回答

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来进行构造/销毁。


谢谢您的解释! - tsmr

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;

如果您不得不使用旧代码,为了避免内存泄漏,在释放myPSL之前,您需要调用Free函数。
myPSL^.Free;
dispose(myPSL);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接