【问题标题】:Correctly allocating/freeing memory for records in static array为静态数组中的记录正确分配/释放内存
【发布时间】:2014-04-08 06:51:40
【问题描述】:

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

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;

我很确定我做的不对,任何建议都将不胜感激。

【问题讨论】:

    标签: delphi delphi-xe4


    【解决方案1】:

    首先要说的是您提供的代码有效。它正确地完成并取消分配而不会泄漏。因此,我将尝试更笼统地回答您的问题。

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

    分配给

    New(PageBase);
    

    然后释放:

    Dispose(PageBase);
    

    New 的调用确保所有受管理的成员都被默认初始化。而在另一个方向,Dispose 将最终确定所有托管成员。

    您可以在代码尝试时手动执行此操作。但在实际代码中,您需要完成数组的每个元素。您的代码只完成了一个。当然,它也只初始化一个,并且正如问题中所写的那样很好。到目前为止,您的问题的简短版本可能已经简化,错误已被消除。

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

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

    【讨论】:

      猜你喜欢
      • 2011-05-16
      • 2013-08-29
      • 2016-03-15
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 2012-01-22
      相关资源
      最近更新 更多