【问题标题】:Delphi memory leak with pointer to TStringList带有指向 TStringList 的指针的 Delphi 内存泄漏
【发布时间】:2017-03-10 03:56:54
【问题描述】:

我在理解指针的行为时遇到了一些麻烦。 我有一个非常简单的例子来演示:

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() 会注意释放相同的内存,那我为什么要需要像“真实”对象一样释放指针吗?

谢谢!

【问题讨论】:

  • 您最初遵循的哪个教程让您陷入了困境?

标签: delphi pointers memory-leaks


【解决方案1】:

类对象已经被指针引用。定义一个指向引用类型的指针意义不大。直接使用类型即可:

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

【讨论】:

  • 感谢您的解释!
【解决方案2】:

您不需要存储指向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);

【讨论】:

    猜你喜欢
    • 2016-05-14
    • 1970-01-01
    • 2018-10-18
    • 2022-01-26
    • 2012-11-15
    • 2013-04-06
    • 1970-01-01
    • 2019-04-18
    • 1970-01-01
    相关资源
    最近更新 更多