2014-04-08 44 views
2

昨天我有一些內存損壞正在進行,我非常懷疑某些記錄數組是如何分配和釋放的。這是演示的簡短版本:正確地爲靜態數組中的記錄分配/釋放內存

type 
    TMyRecord = record 
    W: word; 
    S: String; 
    end; 

    TMyRecordArray = array [1 .. 315] of TMyRecord; 
    TArrayPointer = ^TMyRecordArray; 

var 
PageBase: TArrayPointer; 

procedure TTestForm.FormCreate(Sender: TObject); 
var 
    iRecord: TMyRecord; 
begin 
    PageBase := AllocMem(SizeOf(TMyRecordArray)); 
    iRecord.W := 1; 
    iRecord.S := 'TEST'; 
    PageBase^[1] := iRecord; 
end; 

procedure TTestForm.FormDestroy(Sender: TObject); 
begin 
    PageBase^[1] := Default (TMyRecord); 
    FreeMem(TPageBase); 
end; 

我很確定我沒有這樣做,任何建議,將不勝感激。

回答

7

首先要說的是,你所提供的代碼是有效的。它在不泄漏的情況下正確定位和釋放。所以我會嘗試更普遍地回答你的問題。

字符串是託管類型,編譯器需要使用特殊的內存分配例程來管理它們:NewDispose

分配與

New(PageBase); 

和釋放有:

Dispose(PageBase); 

New的調用確保所管理的任何成員都默認初始化。而在另一方面,Dispose將最終確定任何託管成員。

您可以在代碼嘗試時手動執行此操作。但是在真正的代碼中,您需要完成數組中的每個元素。你的代碼只能完成一個。當然,它也只初始化一個,就像在這個問題中寫的那樣很好。也許你的問題的簡短版本已經簡化到目前爲止,故障已被刪除。

但是,我當然不建議您手動處理託管類型。爲此,請使用NewDispose

同樣值得一提的是,動態數組在這裏會簡單得多。使用動態數組可以讓編譯器負責所有的分配和釋放,並正確處理任何託管類型。

+0

謝謝,這是非常豐富的。 – Walter78

+0

可愛的答案+ 1 –