2017-06-25 2 views
3

次のコードはうまく動作しますが、そうではありません。 Button1をクリックすると、オブジェクトが最初に破棄され、その値が使用され、アクセス違反などが発生しなくなります...さらに、乗算演算によって正しい結果が得られ、Obj1が破棄されないことが証明されます!しかし、もう一度、これはどちらも当てはまりません。なぜなら私がプログラムを閉じるとメモリリークを報告しないからです。私は非常に混乱しています。オブジェクトを破棄した後にオブジェクトを使用すると、例外が表示されないのはなぜですか?

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    MyObj = class(TObject) 
    Value: Cardinal; 
    end; 

    TForm1 = class(TForm) 
    Button1: TButton; 
    procedure FormCreate(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    public 
    Obj1:MyObj; 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
Obj1.Free; 
Obj1.Value:=Obj1.Value * 5; 
Caption:=IntToStr(Obj1.Value); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
ReportMemoryLeaksOnShutdown:=true; 
Obj1:=MyObj.Create; 
Obj1.Value:=10; 
end; 

end. 
+0

メモリがまだ有効なためです。その時点でメモリ位置に書き込んでいるだけです。あなたはその時点で他のオブジェクトの上に落書きしているかもしれません。 –

答えて

5

オブジェクトは破棄されます。メモリはメモリマネージャに返されます。次に起こることはあなたのコントロールから外れています。メモリをシステムに戻すことができます。この場合、実行時エラーが発生します。あるいは、次回プログラムがそのサイズのブロックを要求したときに、メモリマネージャがメモリを再利用する準備が整った状態でメモリを保持することができます。これはここで起こることです。

プログラムは未定義の動作を示します。プログラムが動作するように見えるなど、何かが起こる可能性があります。明らかにプログラムは間違っていて、破壊された後はオブジェクトにアクセスしてはいけません。

完全なデバッグバージョンのFastMMを使用すると、そのシナリオでは無料でアクセスを検出するための手順が取られるため、エラーが表示されます。これは便利なデバッグツールです。

+0

解放されたオブジェクトにNILを割り当てることはできませんか? – GuidoG

+0

@GuidoG NILをその参照に割り当てることは、他の参照がある可能性があるため、必ずしも助けになるとは限りません。 –

+0

@GünthertheBeautifulはい私はぶら下がりポインタの状況を知っているが、彼はObj1:= NIL;自由の後に再び例外を発生させるでしょうか? – GuidoG

関連する問題