gpt4 book ai didi

Delphi 返回 TList 时出错

转载 作者:行者123 更新时间:2023-12-02 13:27:01 26 4
gpt4 key购买 nike

我做了一个非常简单的应用程序,但我有一个我真的无法理解的问题。看一下这个基本代码:

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, generics.collections, Vcl.StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
test: TList<integer>;
aList: TList<integer>;
public
{ Public declarations }
function testGenerics: TList<integer>;
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
test := testGenerics;
test.Sort;
showmessage(test[0].tostring);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
test := TList<integer>.Create;
aList := TList<integer>.Create;
end;

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

function TForm1.testGenerics: TList<integer>;
begin

aList.Add(4);
result := aList;

end;

end.

基本上,当表单打开时,我将创建 testaList然后当我按下按钮时,功能 testGenerics叫做。为什么会出现无效指针操作错误?

我真的无法理解,因为我正在正确地创建和销毁对象(我猜)。这段代码工作正常:

function TForm1.testGenerics: TList<integer>;
begin

Result := TList<integer>.Create;
Result.Add(4);

end;

在本例中,我返回 TList<integer> 的实例但在上面的情况下,我返回一个 aList 的实例(这是一个 TList)。

如果我在第一种情况下是正确的 test := testGenerics就像 test := aList (因为我实际上返回了一个列表)所以我将给出 testaList相同的引用。我对么?

最佳答案

在第一个示例中,每当您调用 testGenerics() 时,您都会重新分配 test 以指向 aList 对象。您无法跟踪在 OnCreate 事件中创建的原始 test 对象,因此它被泄漏。然后在 OnDestroy 事件中,当您调用 test.Free 时,它​​会崩溃,因为您已经事先释放了 aList 对象,因此您正在尝试第二次释放同一个对象,这是无效的操作。

在第二个示例中,您仍然泄漏原始 test 对象(以及您分配并分配给 test 的每个 TList,除了最后一个),但您不再重新分配 test 来指向 aList 对象,因此 OnDestroy 中不会发生崩溃事件,因为两个变量都指向不同的对象。

<小时/>

您首先想要实现什么目标?以这种方式返回对象并不是一个好的做法。在 1 元素列表上调用 Sort() 也没有意义。

如果您尝试随着时间的推移使用多个值填充 test,则应将 test 作为输入参数传递给 testGenerics() (或者只是让 testGenerics() 通过 Self 直接访问 test),根本不使用返回值。

无论如何,请删除您的 aList 私有(private)成员,因为您无论如何都不会用它做任何事情。

试试这个:

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, generics.collections, Vcl.StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
test: TList<integer>;
public
{ Public declarations }
procedure testGenerics(aList: TList<integer>);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
testGenerics(test);
test.Sort;
ShowMessage(test[0].tostring);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
test := TList<integer>.Create;
end;

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

procedure TForm1.testGenerics(aList: TList<integer>);
begin
// FYI, a better way to exercise Sort()
// would be to use RandomRange() instead
// of a hard-coded number...
aList.Add(4);
end;

end.

关于Delphi 返回 TList 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45872925/

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