2017-05-05 20 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; 

コードが正常に動作し、リッチエディットコンポーネント内のアイテムのリストを生成します。私はすでに処理されているオブジェクトを解放していると思われますが、その原因が具体的であるかどうかはわかりません。誰かがこれを説明できますか?

+1

メニューには、item1とitem2の所有権が与えられています。 menu.freeがそれを処理するので、これらのアイテムを解放する必要はありません。 –

+1

これらの様々なタイプが何であるかはわかりませんが、リーフが上に述べたように見えます。 –

+0

これらのメニュークラスが標準のVCLメニュークラスのように動作すると仮定すると、メニュー項目を手動で解放してからメニュー自体を解放するのが安全であるはずです。所有されたオブジェクトは、通常、破壊されたときに所有者から自分自身を削除します。 –

答えて

2

TDcadMenuの実装を見ることはできませんが、通常、クラスに項目を追加すると、その項目の所有権がクラスに与えられますので、クラス外の項目を解放する必要はありません。 @Remyコメントのように、通常はmenuオブジェクトを解放する前に解放するのが通常安全です。あなたのコードで

あなたはitem1を再割り当てされている、との項目を解放するとき、Item1Item2menu.Items[1]と同じインスタンスを共有する両方。これは、あなたが無効なポインタ通知を与えるダブルフリーを持っていることを意味します。

item1.free; 
item2.Free; // <- Double free of same instance 
関連する問題