分配默認(TMyRecord)至TMyRecord的一個變量與所述內部調用第一完成並然後清零等FillChar存儲器會。這在回答以下問題,比如有人說,我也測試分配默認()確實會調用例如System._FinalizeRecord使用Default()賦值來初始化Delphi中的記錄變量是否安全?
How to properly free records that contain various types in Delphi at once?
Difference between Initialize(), Default() and FillChar()
我的問題是不是初始化這樣的記錄,即使在Delphi沒有自動調用Initialize的情況下也是如此?對我來說,在未初始化的記錄變量上調用Finalize似乎沒有任何意義。在初始化之前,必須假定內存包含隨機垃圾。在這種情況下,我特別感興趣的是託管類型,它們是指向動態分配內存的指針,Finalize例程應通過減少其引用計數來完成,等等。在很多情況下,Delphi會自動生成對Initialize的調用,以確保其託管類型保持託管狀態。但不總是。
這裏是示出有問題的情況下的例子。正如下面的答案評論說,你不應該使用的getmem分配包含託管類型這樣的記錄,但讓我們只是假設有人做,然後試圖用默認()分配爲初始化
type
TMyRecord = record
s1, s2, s3 : String;
end;
PMyRecord = ^TMyRecord;
var
pr : PMyRecord;
begin
GetMem(pr, SizeOf(TMyRecord));
pr^ := Default(TMyRecord);
...
我故意使用的getmem ()而不是New(),因爲據我所知,GetMem()返回的內存不應該自動清零,編譯器也不應該自動調用Initialize。所以在這種情況下,使用默認分配初始化記錄不是不安全的嗎?
在大衛在這裏接受的答案,他正在使用的記錄類型一記漂亮的清除方法 How to properly free records that contain various types in Delphi at once? 讓我們添加一個
TMyRecord = record
s1, s2, s3 : String;
procedure Clear;
end;
...
procedure TMyRecord.Clear;
begin
Self := Default(TMyRecord);
end;
現在,清除例程應該絕對沒有辦法知道,如果記錄坐在堆棧或堆上,並且Initialize已被調用,否則。
只是添加,有人可能會說,「怎麼樣AllocMem零分配內存」?但是,使用'GetMem'和'AllocMem'你可以使用'FreeMem',它不能最終確定,而使用'New'你可以使用'Dispose'來確定。 – 2014-12-03 15:57:49
感謝您的深刻評論,但我真的很想具體詢問如何使用Default()賦值來初始化記錄。對我來說,這似乎是一個不好的主意,因爲對我來說,在某些情況下,它似乎有效地調用Finalize處理未初始化的垃圾。 – 2014-12-03 16:30:59
我想你在這種情況下根本不理解我的答案。我無法想出任何更好的表達方式。你對我的回答的評論清楚表明你對這些問題的理解是錯誤的。我不能強迫你改正這一點。 – 2014-12-03 16:33:08