如何使本地数组成为持久数组?

时间:2012-01-31 10:38:01

标签: delphi pointers memory-management delphi-2009 dynamic-arrays

我有一个回调程序:

type
  TInitCallback = procedure (var Data: Pointer);

这个想法是在初始化Data之后可以指向任何东西。

我试图将这个过程分配给回调和init Data,它应该指向一个新创建的数组:

type
  TBoolArray = array of Boolean;

procedure InitData(var Data: Pointer);
var
  BoolArray: TBoolArray;
  i: Integer;
begin
  SetLength(BoolArray, 10);
  for i := 0 to Length(BoolArray) - 1 do
    BoolArray[i] := False;
  Data := BoolArray;
end;

但是,在分配时,我不确定数组的引用计数器是否增加:Data := BoolArray;。换句话说 - 我不确定该数组在离开程序后是否仍在内存中或已被释放?

因为在程序执行的后期,当我更改某些其他结构中的数据(与该数组无关的记录)时,此更改会在先前分配的数组(Data)中进行更改。

对此的一个解释是,在离开回调时释放了数组的内存,并再次重复使用该记录。

那么,在离开InitData回调之后数组是否保持分配状态?如果没有,如何让它保持分配。请注意,我不想更改回调的签名,我不能引入任何新的参数或将其更改为函数。

谢谢。

1 个答案:

答案 0 :(得分:5)

您认为动态数组的引用计数在分配给Data时不会递增,这是正确的。这意味着当InitData返回时,本地数组超出范围。因此你的代码就被打破了。

最简单的解决方案是将TInitCallback的定义更改为使用动态数组,然后引用机制将为您管理生命周期。由于您不希望更改界面,因此您(至少)有以下选项:

  1. 使BoolArray成为全局变量。只有在您的应用程序中只有一个实例时,这才有效。
  2. BoolArray的类型更改为^TBoolArray并使用New在堆上分配此值。您还需要添加另一个过程,通过调用Dispose来解除分配数组。
  3. 与选项2非常相似,将数组包装在一个类中。类实例可以安全地存储在指针中。同样,您需要通过调用Free来处理类实例的另一个函数。