2014-04-08 105 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 –