2017-09-26 45 views
0

我最大限度地簡化了下面的代碼,只顯示我的問題。 當析構函數TClass3.Destroy完成時,動作FreeAndNil(FClass3)會導致問題,程序將停止。如果有在Heap.trc文件一看,我可以在0000000001528FD0 $無效讀爲什麼我用HeapTrc獲得錯誤的簽名?

已標記內存
錯誤簽名$ 2951FD2D而不是5C063D8B

program Project_testFree; 
{$mode objfpc}{$H+} 

uses 
    sysutils; 

type 
    TClass1 = class 
    private 
    protected 
    public 
    constructor Create; 
    end; 

    TClass2 = class(TClass1) 
    private 
    protected 
    FTClass2 : cardinal; 
    public 
    end; 

    TClass3 = class 
    private 
    protected 
    FClass3  : TClass1; 
    public 
    constructor Create;virtual; 
    destructor Destroy;override; 
    end; 

    TClass4 = class(TClass3) 
    private 
    function GetLocalClass2: TClass2; 
    protected 
    public 
    constructor Create;override; 
    destructor destroy;override; 
    property pClass2:TClass2 read GetLocalClass2; 
    end; 

constructor TClass1.Create; 
begin 
    inherited; 
end; 

constructor TClass3.Create; 
begin 
    FClass3    := TClass1.create; 
end; 

destructor TClass3.Destroy; 
begin 
    FreeAndNil(FClass3); 
    writeln('Destroy'); 
    inherited Destroy; 
end; 

constructor TClass4.Create; 
begin 
    inherited Create; 
    pClass2.FTClass2 := 1; 
end; 

destructor TClass4.destroy; 
begin 
    inherited destroy; 
end; 

function TClass4.GetLocalClass2: TClass2; 
begin 
    result := TClass2(FClass3); 
end; 

var 
    c:TClass4; 
begin 
    if FileExists('heap.trc') then 
    DeleteFile('heap.trc'); 
    SetHeapTraceOutput('heap.trc'); 

    c:=TClass4.Create; 
    c.free; 
end. 

我使用的拉撒路1.6.2。 感謝您的幫助。

+0

代碼堆損壞?無論如何,這可能與您的問題無關,但您應始終在文件名中包含明確的絕對路徑。 – MartynA

+0

我認爲這與我的問題無關,如果我想讓文件位於我的應用程序的同一目錄中,我不認爲絕對路徑是必需的 –

+0

您是否假設您有對您的應用程序目錄的寫入權限? – MartynA

回答

3

您將FClass3轉換爲TClass2。但是你實例化了TClass1。因此演員陣容不正確,可以解釋錯誤。基本上,你對編譯器撒謊,並且報復了它。

如果您使用了檢查強制轉換,使用as,那麼會產生運行時錯誤。

+0

你是對的大衛,我沒有看到它。我會重申一個不能確定的重要事情。正如你用'as'寫的那樣提出了一個錯誤。我將重新安排我的代碼,如**構造函數TClass4.Create;開始繼承創建; FLocalClass2:= TClass2.Create; FLOcalClass2.FTClass2:= 1;結束;析構函數TClass4.destroy;開始FreeAndNil(FLocalClass2);繼承破壞;結束; ** –

+0

你需要清理你的類的命名。你也不應該命名實例類。 –

相關問題