我的代码包含以下所示的基本结构:
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.
直到函数开始返回空数组时,它一直工作正常。然后我发现this,这使我明白了简单分配不正确的事实,我需要使用Copy
。
两个问题:
Note 1
的行上'复制'以分配给
功能结果。我是否还需要在分配时使用Copy
数组a
的函数结果(行Note 2
)?。我意识到我可以尝试这些东西然后看看,但是我对编译器让我感到疑惑的事情感到有点震惊。
答案 0 :(得分:3)
没有理由在任何一个赋值语句中使用Copy
。正常分配工作正常。当您分配b
时,数组的引用计数为1.当您将其分配给Result
时,引用计数变为2.(就个人而言,我只是放弃b
并进行操作直接从Result
开始。)当函数返回时,b
超出范围,引用计数再次变为1。最后,当结果分配给a
时,没有任何反应,因为Result
实际上是a
的别名。最终,你留下了一个独特的阵列,这应该是你想要的。
编译器允许您的代码,因为您的代码很好。编译器识别数组之间的赋值,就像它在字符串和接口引用之间的赋值之间进行分配一样,它会生成正确的代码来相应地调整引用计数。
使用Copy
会创建数组的完整副本,但您不需要。每当你认为你需要它时,它就会在你无论如何都会立即丢弃之前的副本的地方。当你已经有一个非常好的阵列准备好你想要的任何用途时,为什么要复制?