内存泄漏与访问冲突,类设计问题

Fra*_*anz 0 delphi memory-leaks

我在下面的代码中为用户类显示了一个简短的设计模式.

type
  MytestClass = class
    alist: TStringlist;
  public
    constructor Create;
    destructor destroy; override;
  end;
  { MytestClass }

type
  TForm1 = class(TForm)
    btn_version01: TBitBtn;
    btnversion02: TBitBtn;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure btn_version01Click(Sender: TObject);
    procedure btnversion02Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }

    btestClass : MytestClass;
    aComplexClassDesign : TComplexClassDesign;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

constructor MytestClass.Create;
begin
  alist := TStringlist.Create;
end;

destructor MytestClass.destroy;
begin
  alist.free;
  inherited;
end;


procedure TForm1.btnversion02Click(Sender: TObject);
var atestClass : MytestClass;
begin
     ///
  atestClass :=MytestClass.Create;
  atestClass.Free;
  atestClass := nil;
end;

procedure TForm1.btn_version01Click(Sender: TObject);
var atestClass : MytestClass;
begin
     ///
  atestClass :=MytestClass.Create;
  atestClass.Free;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  btestClass.free;
  aComplexClassDesign.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  btestClass :=MytestClass.Create;
  aComplexClassDesign :=TComplexClassDesign.Create;
end;

end.
Run Code Online (Sandbox Code Playgroud)

希望这是一个完美的设计,没有内存泄漏和访问冲突.我在实际应用程序中使用的所有类都是按照这种模式设计的.

在上面的代码中,FastMM4在我的TComplexClassDesign上没有出现任何问题.在真正的应用程序中,FASTMM4报告了我的TComplexClassDesign的内存泄漏,甚至我在窗体的Close Event中调用了free函数.如果我单步执行代码以确保执行此功能.知道如何调试这个内存泄漏报告,任何选项都可以看到尚未发布的TComplexClassDesign实例?我得到这个奇怪的内存泄漏报告的任何其他原因?

奖金问题:

DUnit总是像这样制作拆解代码

  atestClass :=MytestClass.Create;
  atestClass.Free;
  atestClass := Nil
Run Code Online (Sandbox Code Playgroud)

最后一行代码真的需要吗?

Dav*_*nan 7

这是一个错误的匹配OnCreateOnClose.那些事件不是一对.该OnCreate事件在施工期间被调用.破坏的匹配事件是OnDestroy.你创造的任何东西OnCreate都应该被摧毁OnDestroy.

我个人认为在价值不大OnCreateOnDestroy.我总是选择覆盖虚构造函数和析构函数.


procedure TForm1.FormCreate(Sender: TObject);
begin
  btestClass :=MytestClass.Create;
  aComplexClassDesign :=TComplexClassDesign.Create;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  btestClass.free;
  aComplexClassDesign.Free;
end;
Run Code Online (Sandbox Code Playgroud)

作为一般规则,以与创建相反的顺序销毁对象.这没关系,但如果对象有依赖关系,那么顺序有时很重要.


procedure TForm1.btnversion02Click(Sender: TObject);
var atestClass : MytestClass;
begin
  atestClass :=MytestClass.Create;
  atestClass.Free;
  atestClass := nil;
end;
Run Code Online (Sandbox Code Playgroud)

分配nil给有什么意义atestClass吗?绝对不.此变量在赋值后立即离开作用域,因此任何其他代码都无法观察到结果赋值.我希望编译器能够对此发出警告.它会在您进行分配时发出警告,但从不使用指定的值.我希望你已启用警告.


最后,为什么你的真实代码有内存泄漏?无法从这里说出来.FastMM的完整调试版本为泄漏报告提供了丰富的堆栈跟踪.这些跟踪将包括导致分配泄漏对象的调用堆栈.

  • 大声笑 - 当你需要做的就是回答*奖励*问题时,为什么还要写出*实际*问题的详细答案. (2认同)