1

我的代码具有以下说明的基本结构:

type
    TDynamicArray = array of double ;

var
    a : TDynamicArray ;

    function Func : TDynamicArray ;

    var
        b : TDynamicArray ;

    begin
    SetLength (B, 3) ;
    b [0] := 0.0 ;
    b [1] := 1.0 ;
    b [2] := 2.0 ;
    Result := b ;   // note 1  -- should use Result := Copy (b, 0, Length (b)) 
    end ;

begin
a := Func ;  // note 2  -- should we (or could we) use a := Copy (Func, 0, Length (Func)) 
end.

直到最近该函数开始返回空数组时,它一直运行良好。然后我发现了这一点,这让我意识到简单的分配是不正确的,我需要使用Copy.

两个问题:

  • 我意识到我需要在标记的行上“复制”Note 1以分配给函数结果。我是否Copy还需要将函数结果分配给数组a(行Note 2)?
  • 为什么编译器允许我的构造以及编译后的代码实际上在做什么?

我意识到我可以尝试这些事情并看看,但我有点害怕编译器让有问题的东西通过。

4

1 回答 1

3

没有理由Copy在这些赋值语句中使用。正常分配工作正常。当你 allocateb时,数组的引用计数为 1。当你将它分配给 时Result,引用计数变为 2。(我个人只是放弃b并直接Result从头开始操作。)当函数返回时,b退出范围和引用计数再次变为 1。最后,当结果分配给 时a,什么也没有发生,因为Result实际上一直是别名a。最终,您只剩下一个独特的数组,这应该正是您想要的。

编译器允许您的代码,因为您的代码很好。编译器识别数组之间的分配,就像它识别字符串之间的分配和接口引用之间的分配一样,它会生成正确的代码来相应地调整引用计数。

使用Copy会创建数组的完整副本,但您不需要它。每次你认为你需要它时,它都放在一个无论如何你都会立即丢弃以前的副本的地方。当您已经准备好一个完美的阵列以供您想要的任何用途时,为什么还要制作副本?

于 2013-10-02T02:31:16.320 回答