Delphi:内存泄漏警告消息

时间:2015-04-19 16:00:09

标签: delphi memory-leaks delphi-2006

我正在Delphi 2006中创建一个小应用程序。在其中一个类中有另一个类的属性。在我的onCreate事件中,我实例化了对象,并在onDestroy事件中销毁它们。当我关闭应用程序时,我收到内存泄漏警告。老实说,我无法识别内存泄漏。以下是我正在使用的代码,非常感谢您的帮助。

我无法发布错误消息的图片,但这是一个描述。

An unexpected memory leak has occurred. The unexpected small block leaks are:
21 - 28 bytes: TPermanentAddress x 1

这是班级:

unit uUser;

interface

uses
  classes,SysUtils,Dialogs;


type
TAddress = class
private
 FStreetAddress : string;
 FCity          : string ;
 FState         : string;
 FZipCode       : string;

 procedure setStreetAddress(const Value : string);
 procedure setCity(const Value : string);
 procedure setState(const Value : string);
 procedure setZipCode(const Value : string);

 protected

 public
 property StreetAddress : string read FStreetAddress write setStreetAddress;
 property City : string read FCity write setCity;
 property State : string read FState write setState;
 property ZipCode : string read FZipCode write setZipCode;


end;

type
  TPermanentAdddress = class (TAddress)
  private
  FStartDate     : string;
  FEndDate       : string;

  procedure setStartDate(const Value : string);
  procedure setEndDate(const Value : string);

  protected

  public

  property StartDate : string read FStartDate write setStartDate;
  property EndDate   : string read FEndDate write setEndDate ;
  end;


type
TUser = class(TObject)
  private
  FFirstName : string;
  FAddress : TPermanentAdddress;
  procedure setFirstName(const Value : string);
  procedure setAddress(const Value : TPermanentAdddress);

  protected

  public
  constructor Create(); reintroduce; overload;
  destructor Destroy();  override;
   property FirstName : string read FFirstName write setFirstName;
   property Address : TPermanentAdddress read FAddress write setAddress;

end;

implementation

procedure TAddress.setStreetAddress(const Value : string);
begin
  FStreetAddress := value;
end;

 procedure TAddress.setCity(const Value : string);
 begin
   FCity := Value;
 end;
 procedure TAddress.setState(const Value : string);
 begin
   FState := Value;
 end;
 procedure TAddress.setZipCode(const Value : string);
 begin
   FZipCode := Value;
 end;

 //Permanent Address
  procedure TPermanentAdddress.setStartDate(const Value : string);
  begin
    FStartDate := value;
  end;
  procedure TPermanentAdddress.setEndDate(const Value : string);
  begin
    FEndDate := Value;
  end;

  //tvxpatient
  procedure TUser.setFirstName(const Value : string);
  begin
    FFirstName := Value;
  end;
  procedure TUser.setAddress(const Value : TPermanentAdddress);
  begin
    FAddress := Value;
  end;

  constructor TUser.Create();
  begin
   FAddress := TPermanentAdddress.Create;
  end;

  destructor TUser.Destroy();
  begin
  //FAddress.Free;
  end;

end.

这是表格:

unit Home;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uUser, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
protected

  public
    { Public declarations }
  aUser : TUser;

  end;
var
  Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
addr : TPermanentAdddress;
begin
  aUser := TUser.Create;
  aUser.Address := TPermanentAdddress.Create;
  aUser.FirstName := 'test';
  aUser.Address.StartDate := '03/10/2015';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 aUser.Address.Free; // I am destroying it here, so I thought.
 aUser.Free;
end;

end. 

在项目中,我打开了ReportMemoryLeaksOnShutdown。

program Testing;

uses
  Forms,
  Home in 'Home.pas' {Form1},
  uUser in 'uUser.pas';

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

1 个答案:

答案 0 :(得分:4)

destructor TUser.Destroy();
begin
  //FAddress.Free;
end;

在这里你无法摧毁FAddress。因此内存泄漏。

您还应该调用继承的析构函数。它应该是这样的:

destructor TUser.Destroy;
begin
  FAddress.Free;
  inherited;
end;

除此之外,你错误地创建Address两次。而不是:

procedure TForm1.FormCreate(Sender: TObject);
var
  addr : TPermanentAdddress;
begin
  aUser := TUser.Create;
  aUser.Address := TPermanentAdddress.Create;
  aUser.FirstName := 'test';
  aUser.Address.StartDate := '03/10/2015';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 aUser.Address.Free; // I am destroying it here, so I thought.
 aUser.Free;
end;

你需要:

procedure TForm1.FormCreate(Sender: TObject);
begin
  aUser := TUser.Create;
  aUser.FirstName := 'test';
  aUser.Address.StartDate := '03/10/2015';
end;

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

我个人会使用TForm1而不是OnCreateOnDestroy的构造函数/析构函数来管理自有对象。