Ashlar
Ashlar

Reputation: 676

Another Delphi Invalid Pointer Operation

This VCL Form program generates the Invalid Pointer Operation notice:

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;

The code works fine and generates the item list in the Richedit component. I suspect I am freeing an object that is already being handled, but not clear on what the cause is specifically. Can someone explain this?

Upvotes: 1

Views: 606

Answers (1)

LU RD
LU RD

Reputation: 34899

We can't see the implementation of TDcadMenu, but normally adding items to a class gives the ownership of the items to that class, so there is no need to free the items outside of the class. As @Remy comments, it is normally safe to free them before before freeing the menu object, though.

In your code you are reassigning item1, and when freeing the items, Item1 and Item2 both shares the same instance as menu.Items[1]. This means that you have a double free, which gives your invalid pointer notice.

item1.free;
item2.Free;  // <- Double free of same instance

Upvotes: 2

Related Questions