Delphi Seattle:释放我创建的对象时,我得到了无效的指针操作

Jac*_* N. 5 delphi delphi-10-seattle

我使用的是Delphi Seattle。

当我尝试释放创建的对象时出现我的问题。

我在该站点(以及其他站点)中搜索了已经发布的针对该问题的答案,但是它们都有些不同。根据这些讨论,我的代码应该可以工作,但是显然有些事情并不正确。

所以,我需要帮助...

执行流程:

a)在形式fmLoanRequest中,我基于类TStorageLoan(TLoan的子类)创建一个对象。构造函数将所有类型的值加载到对象的某些属性中(在此处显示)。

b)以后,我将对象的地址传递给另一形式(fmLoan)到适当的公共变量。fmLoan是所有用户处理贷款内容的形式。请注意,当我们在fmLoan中时,fmLoanRequest保持不变。当fmLoan关闭时,我们将返回到fmLoanrequest。

c)显示表格(并显示对象中的数据-一切正常)。

d)关闭fmLoan时,将调用一个过程以释放贷款对象-如果已分配该对象(请参见第二代码段的 10行)。看来工作正常(没有错误)。

e)当执行下面第14行中的代码时,发生“无效指针操作”错误:( 如果为Assigned(oLoan),则为oLoan.Free;)。

我添加了这一行,以确保如果fmLoan由于某种原因不处理该对象,则该对象将被释放。我意识到此时对象已被释放,但是'if Assgned()'是否应该防止不必要的对象释放?

来自表单fmLoanRequest的部分代码(我添加了一些行号以供参考)

1  // In form fmLoanRequest 
2  // Create new Loan Object (from a Loan sub-class as it happens)
3    // Create the object here; Object address will be passed to fmLoan later for handling.
4    oLoan := TStorageLoan.Create(iNewLoanID);
5  ...
6  ...
7     fmLoan.oLoan := oLoan; // pass the address to the other form
8     fmLoan.show;
9     // User would click the 'btnClose' at this point. See event code below.
10  ...
11  ...
12    procedure TfmLoanRequests.btnCloseClick(Sender: TObject);
13    begin 
14      if Assigned(oLoan) then oLoan.Free; // <--- ERROR HERE 
15      fmLoanRequests.Close;
16  end;
Run Code Online (Sandbox Code Playgroud)

来自fmLoan表格的部分代码(我添加了一些行号以供参考)

1  //Form fmLoan
2  ...
3    public
4      oLoan : TLoan;
5  ... 
6  // In form fmLoan, I call the following upon closing the Form
7  //                 in the OnClick event of the 'btnClose' button. 
8  Procedure TfmLoan.Clear_Loan_Object;
9  begin
10    if Assigned(oLoan) then oLoan.Free; // <-- THIS WORKS FINE
11  end;
Run Code Online (Sandbox Code Playgroud)

我应该尝试其他方法吗?

我是否应该删除该行(第14行-第一个代码段),并希望取得最佳效果。那根本不是我关于正确编码的理念!

我会以错误的方式去做吗?

注意:我显然不使用指针。

任何帮助,将不胜感激!

Rem*_*eau 2

很明显,您两次释放 Loan 对象,这就是您收到错误的原因。您只需释放它一次。 fmLoanRequests创建对象,但你说它可以在fmLoan关闭之前关闭,因此应该取得该对象的所有权并在关闭fmLoan时释放它。关闭fmLoan时根本不要释放该对象。fmLoanRequest

另一种方法是定义一个ILoan接口,TLoan并由其后代实现,然后传递ILoan而不是TLoan直接传递。接口是引用计数的,因此 Loan 对象将自动释放,并且仅释放一次,在 和 都fmLoanRequests释放fmLoan了对它的引用之后。