2017-05-05 70 views
0

這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組件項目列表。我懷疑我正在釋放一個已經被處理的對象,但不清楚具體原因是什麼。有人可以解釋這個嗎?

+1

您將item1和item2的所有權賦予菜單。沒有必要釋放這些項目,因爲menu.free會照顧到這一點。 –

+1

我們不知道這些類型是什麼,但它看起來像Lief上面所說的。 –

+0

假設這些菜單類可以像標準的VCL菜單類一樣工作,那麼在釋放菜單本身之前手動釋放菜單項應該是安全的。擁有物品通常會在被銷燬時從其所有者身上移除。 –

回答

2

我們看不到TDcadMenu的實現,但通常將項目添加到類中會將項目的所有權交給該類,因此不需要將項目釋放到類之外。正如@Remy所言,儘管釋放menu對象之前釋放它們通常是安全的。

在你的代碼被重新分配item1,並釋放物品,Item1Item2都共享相同的實例作爲menu.Items[1]時。這意味着你有一個雙免費的,這使你的無效指針通知。

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