0

这个 VCL Form 程序生成 Invalid Pointer Operation 通知:

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 组件中生成项目列表。我怀疑我正在释放一个已经被处理的对象,但不清楚具体原因是什么。有人可以解释一下吗?

4

1 回答 1

2

我们看不到 的实现TDcadMenu,但通常将项目添加到类中会将项目的所有权授予该类,因此无需在类之外释放项目。menu正如@Remy 评论的那样,通常在释放对象之前释放它们是安全的。

在您的代码中,您正在重新分配item1,并且在释放项目时,Item1两者都与 .Item2共享相同的实例menu.Items[1]。这意味着您有一个双重释放,它会通知您的无效指针。

item1.free;
item2.Free;  // <- Double free of same instance
于 2017-05-06T08:21:18.557 回答