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

发布于 2025-01-01 16:57:05 字数 778 浏览 5 评论 0原文

我有一个回调过程:

type
  TInitCallback = procedure (var Data: Pointer);

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

我尝试将此过程分配给回调并初始化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;

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

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

对此的一种解释是,当离开回调时,数组的内存被释放,并再次重新用于记录。

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

谢谢。

I have a callback procedure:

type
  TInitCallback = procedure (var Data: Pointer);

The idea is that after initialization Data could point to anything.

I've tried to assign this procedure to the callback and init Data in a way that it should point to a newly created array:

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;

However, I am not sure that reference counter is increased for array when assigning: Data := BoolArray;. In other words - I am not sure that array is still in memory after leaving the procedure or has it been freed?

Because later in a program execution, when I change the data in some other structure ( a record which has nothing to do with this array), this change makes changes in earlier allocated array(Data).

One explanation for this would be that the memory for array was freed when leaving the callback and reused once again for the record.

So, does the array stays allocated after leaveing InitData callback or not? And if not, how to make it stay allocated. Please not that I do not want to change the signature of my callback, I can not introduce any new params or change it to a function.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

南风起 2025-01-08 16:57:05

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

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

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

You are correct in your assumption that the reference count of the dynamic array is not incremented when you assign to Data. This means that the local array goes out of scope when InitData returns. Thus your code is broken.

The most simple solution would be to change the definition of TInitCallback to use a dynamic array and then the reference mechanism would manage the lifetime for you. Since you do not wish to change your interface then you have (at least) the following options:

  1. Make BoolArray a global variable. That would only work if there is only one instance in your application.
  2. Change the type of BoolArray to ^TBoolArray and use New to allocate this on the heap. You would also need to add another procedure which would deallocate the array with a call to Dispose.
  3. Very similary to option 2, wrap the array in a class. Class instances can be safely stored in pointers. Again you would need another function to dispose of the class instance by calling Free.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文