使用Delphi XE 5进行PPointerList访问冲突

时间:2014-05-26 13:55:09

标签: delphi delphi-xe5

在使用Delphi XE5运行以下简单代码时,我获得了AccessViolation:

  

0x0040213c处的访问冲突:写入地址0x00000000

Delphi 2009没有任何问题!从那以后发生了什么变化?!

program consola;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Classes;

type
  MyRecord = Record
    name : string;
    age  : Integer;
  end;

var
  recPointer : ^MyRecord;
  FList: PPointerList;

begin
  New(recPointer);
  recPointer.name := 'Brian';
  recPointer.age  := 23;

  GetMem(FList, 4 * SizeOf(recPointer));

  FList^[0] := recPointer;
end.

2 个答案:

答案 0 :(得分:2)

您是否在XE5上看到了PPointerList的声明?这是指向动态数组的指针

从帮助中摘录:

Delphi type PPointerList = ^TPointerList;
Delphi type TPointerList = array of Pointer;

所以可能的用法是:

  New(Flist);
  SetLength(Flist^, 4);

  FList^[0] := recPointer;

(当然,PPointerList在这里没用,它足以利用TPointerList)

答案 1 :(得分:2)

您在这里使用了错误的类型。您的FList变量是指向无类型指针的动态数组的指针。这根本不是你需要的。而且你没有正确分配内存。我不打算尝试更多地解释您的代码,因为您当前的方法存在根本缺陷。

您应该使用动态数组或TList<MyRecord>。前者看起来像这样:

var
  Arr: TArray<MyRecord>;
....
SetLength(Arr, 4);
Arr[0].Name := ...

后者:

var
  List: TList<MyRecord>;
  Rec: MyRecord;
....
List := TList<MyRecord>.Create;
Rec.Name := ...
List.Add(Rec);

您的代码是灾难的秘诀。即使您修复了允许使用GetMem分配的类型,您将如何处理记录的托管字符串成员的管理。通过使用类型安全的数据结构使生活更轻松,因此允许编译器完成繁重的工作。