正确地为静态数组中的记录分配/释放内存

Wal*_*r78 3 delphi delphi-xe4

昨天我发生了一些内存损坏,我非常怀疑一些记录数组是如何被分配和释放的.这是演示的简短版本:

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;
Run Code Online (Sandbox Code Playgroud)

我很确定我做得不对,任何建议都会受到赞赏.

Dav*_*nan 8

首先要说的是你提出的代码是有效的.它在没有泄漏的情况下正确地完成并解除分配.所以我会更广泛地回答你的问题.

字符串是托管类型,编译器需要使用特殊的内存分配例程来管理它们:NewDispose.

分配

New(PageBase);
Run Code Online (Sandbox Code Playgroud)

并取消分配:

Dispose(PageBase);
Run Code Online (Sandbox Code Playgroud)

调用以New确保管理的任何成员都是默认初始化的.在另一个方向,Dispose将最终确定任何管理成员.

您可以在代码尝试时手动执行此操作.但在实际代码中,您需要最终确定数组的每个元素.您的代码只能完成一个.当然,它也只初始化一个,并且在问题中写的很好.也许你的问题的简短版本到目前为止已经简化,故障已被删除.

但是,我当然不建议您手动处理托管类型.使用NewDispose为此.

值得一提的是,动态数组在这里会简单得多.使用动态数组可以让编译器负责所有的分配和释放,并正确处理任何托管类型.