Delphi过程中的数组参数混淆

4
我这里有一个问题,但我不理解它:

我这里有一个问题,但我不理解它:

procedure TMain.THREAD_SYNC(
              AProgressBar: TProgressBar; 
              ARemoteData: array of RemoteDATA; 
              ALocalData : array of LocalDATA; 
              Number : integer; 
              AInfo : TEdit);

如果我将“较小的数组”分配给它,则以下过程完美运行。

THREAD_SYNC(Remote,Local,0,Edit1)

当我尝试把一个超过30,000条记录的更大数组分配给它时,会出现堆栈溢出错误,所以我尝试并搜索... 我发现可以使用const来解决这个问题,所以我修改了我的程序如下:

procedure TMain.THREAD_SYNC(
              AProgressBar: TProgressBar; 
              ARemoteData: array of RemoteDATA; 
              const ALocalData : array of LocalDATA; 
              Number : integer; 
              AInfo : TEdit);

现在它可以工作了,但我不理解为什么?
没有 const 有什么区别吗?

1个回答

6

这些数组是按值传递的,这意味着它们被复制到堆栈上并通过该方式传递。因此会出现堆栈溢出错误。

通过使数组参数成为 const,可以解决该问题。在这种情况下,数组是通过引用而不是值传递的。换句话说,只传递一个指针。

通常情况下,当传递(可能是)大型结构,如数组或记录时,应始终通过引用传递它们;如果接收数据的方法不改变数据,则使用 const,如果接收方需要更改数据,则使用 var。这还具有额外的好处,因为无需复制数据,代码变得更快。

你应该将你的方法更改如下:

procedure TMain.THREAD_SYNC(
              AProgressBar: TProgressBar; 
              const ARemoteData: array of RemoteDATA; 
              const ALocalData : array of LocalDATA; 
              Number : integer; 
              AInfo : TEdit);

不需要对 TProgressBar 或者 TEdit 使用 const,因为它们是类(class),而类被存储在堆(heap)上,只有栈(stack)上的引用。

2
它看起来是这样的,但实际上,首先传递一个单一指针,当参数不是const时,被调用者(THREAD_SYNC)使用该指针复制数组。虽然效果相同:堆栈溢出。 - Rudy Velthuis
顺便提一下,这是有文档记录的:http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Program_Control_(Delphi) :“值和常量(const)参数根据参数的类型和大小传递值或引用”。 - Rudy Velthuis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接