另一个 Delphi 无效指针操作
Another Delphi Invalid Pointer Operation
此 VCL 窗体程序生成无效指针操作通知:
Uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
DcadMenu_u;
type
TForm1 = class(TForm)
MenuTestRichEdit: TRichEdit;
LoadButton: TButton;
procedure ButtonLoadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ButtonLoadClick(Sender: TObject);
var
menu : TDcadMenu;
item1, item2 : TDcadMenuItem;
strlist :tstringlist;
i : integer;
begin
menu := tDcadMenu.Create();
item1 := TDcadMenuItem.create ('Option1', 'Do Option1', false, false, true);
menu.add (item1);
item2 := TDcadMenuItem.create ('Option2', 'Do Option2', false, false, true);
menu.add (item2);
strlist := tstringlist.Create;
Try
For i := 0 to Menu.Count - 1 DO
begin
item1 := menu.Items[i];
strlist.Add (Item1.lblset + ' | ' + Item1.lblmsg );
end;
Form1.MenuTestRichEdit.Lines := strlist;
finally
item1.free;
item2.Free;
menu.free;
strlist.Free;
end;
end;
代码运行良好,并在 Richedit 组件中生成项目列表。我怀疑我正在释放一个已经被处理的对象,但不清楚具体原因是什么。有人可以解释一下吗?
我们看不到 TDcadMenu
的实现,但通常将项目添加到 class 会将项目的所有权赋予 class,因此无需释放 class 之外的项目。正如@Remy 评论的那样,在释放 menu
对象之前释放它们通常是安全的。
在您的代码中,您正在重新分配 item1
,并且在释放项目时,Item1
和 Item2
都与 menu.Items[1]
共享同一个实例。这意味着您有一个双重释放,它会发出无效指针通知。
item1.free;
item2.Free; // <- Double free of same instance
此 VCL 窗体程序生成无效指针操作通知:
Uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls,
DcadMenu_u;
type
TForm1 = class(TForm)
MenuTestRichEdit: TRichEdit;
LoadButton: TButton;
procedure ButtonLoadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ButtonLoadClick(Sender: TObject);
var
menu : TDcadMenu;
item1, item2 : TDcadMenuItem;
strlist :tstringlist;
i : integer;
begin
menu := tDcadMenu.Create();
item1 := TDcadMenuItem.create ('Option1', 'Do Option1', false, false, true);
menu.add (item1);
item2 := TDcadMenuItem.create ('Option2', 'Do Option2', false, false, true);
menu.add (item2);
strlist := tstringlist.Create;
Try
For i := 0 to Menu.Count - 1 DO
begin
item1 := menu.Items[i];
strlist.Add (Item1.lblset + ' | ' + Item1.lblmsg );
end;
Form1.MenuTestRichEdit.Lines := strlist;
finally
item1.free;
item2.Free;
menu.free;
strlist.Free;
end;
end;
代码运行良好,并在 Richedit 组件中生成项目列表。我怀疑我正在释放一个已经被处理的对象,但不清楚具体原因是什么。有人可以解释一下吗?
我们看不到 TDcadMenu
的实现,但通常将项目添加到 class 会将项目的所有权赋予 class,因此无需释放 class 之外的项目。正如@Remy 评论的那样,在释放 menu
对象之前释放它们通常是安全的。
在您的代码中,您正在重新分配 item1
,并且在释放项目时,Item1
和 Item2
都与 menu.Items[1]
共享同一个实例。这意味着您有一个双重释放,它会发出无效指针通知。
item1.free;
item2.Free; // <- Double free of same instance