gpt4 book ai didi

delphi - FastMM 报告 FormDestroy 上释放的类存在内存泄漏

转载 作者:行者123 更新时间:2023-12-03 15:48:29 25 4
gpt4 key购买 nike

我在 Delphi 7 应用程序(CLX)中遇到了内存泄漏问题,代码如下:

unit Unit2;

interface

uses ECRClass, ECR_Text, SysUtils, Types, Classes, Variants, Math;

type tLeakClass = class
private
fsType : integer;

public
fsPrinter : TECR_Class;

published
constructor Create (AOwner : TComponent);
destructor Destroy();
end;


implementation

constructor tLeakClass.Create (AOwner : TComponent);
begin
fsPrinter := TECR_Text.Create(AOwner);
end;

destructor tLeakClass.Destroy();
begin
fsPrinter.Free
end;

end.

对象fsPrinter结果泄漏,即使它在主窗体(TForm)关闭时被释放:

unit Unit1;

interface

uses
SysUtils, Types, Classes, Variants, QTypes, QGraphics, QControls, QForms,
QDialogs, QStdCtrls, Unit2;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
tleak : tLeakClass;
end;

var
Form1: TForm1;

implementation

{$R *.xfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
tLeak := tLeakClass.Create(Self);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
tleak.Free
end;

end.

这是 FastMM4 的泄漏报告:

A memory block has been leaked. The size is: 740

This block was allocated by thread 0xBA8, and the stack trace (return addresses) at the time was:
402F1C [system.pas][System][@GetMem][2439]
403C77 [system.pas][System][TObject.NewInstance][8360]
404012 [system.pas][System][@ClassCreate][9019]
502F15 [ECR_Text.pas][ECR_Text][TECR_Text.Create][101]
403C80 [system.pas][System][TObject.NewInstance][8360]
404012 [system.pas][System][@ClassCreate][9019]
5030C6 [Unit2.pas][Unit2][tLeakClass.Create][24]
43856C [QStdCtrls.pas][QStdCtrls][2863]
503300 [Unit1.pas][Unit1][TForm1.Button1Click][30]
447076 [QControls.pas][QControls][TControl.Click][1977]
43858C [QStdCtrls.pas][QStdCtrls][TButton.Click][2871]

The block is currently used for an object of class: TECR_Text

Here您可以下载完整的SSCCE代表问题的项目示例(要运行该示例,只需单击按钮并关闭表单)。

为什么fsPrinter对象泄漏?如何避免泄漏?

最佳答案

您的析构函数声明不正确。您写道:

destructor Destroy();

但是您必须覆盖 TObject 中声明的虚拟析构函数。如果您不这样做,那么您的析构函数将不会被 Free 调用,它会调用 TObject 中声明的虚拟析构函数。

像这样修复它:

destructor Destroy(); override;

尽管在这种情况下并不重要,但您应该养成在构造函数和析构函数中调用继承的构造函数和析构函数的习惯。这样,当您从一个在其构造函数和析构函数中执行的操作多于 TObject 的类派生时,您将确保父类(super class)代码能够运行。

constructor tLeakClass.Create (AOwner : TComponent);
begin
inherited Create;
fsPrinter := TECR_Text.Create(AOwner);
end;

destructor tLeakClass.Destroy();
begin
fsPrinter.Free;
inherited;
end;
<小时/>

FastMM 的报告有点奇怪。它报告 TECR_Text 对象已泄漏。但由于您创建了该表单所拥有的内容,因此表单应该将其删除。问题代码中明显泄漏的对象是tLeakClass

的实例

所以我怀疑类中还有其他我们看不到的问题。您很可能犯了同样的错误,并忽略了我们看不到的类析构函数的覆盖

关于delphi - FastMM 报告 FormDestroy 上释放的类存在内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15731052/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com