我决定不使用一般的TList<integer>,而是决定使用

TSolutions = array of integer;

进而:
function TEuclidMod.gcdExtended(p, q: integer): TSolutions;
var tmpArr: TSolutions;
begin

 SetLength(tmpArr, 3);

 if (q = 0) then
  begin
   tmpArr[0] := p;
   tmpArr[1] := 1;
   tmpArr[2] := 0;
  end
 else
  begin
   vals := gcdExtended(q, modulo(p,q));
   tmpArr[0] := vals[0];
   tmpArr[1] := vals[2];
   tmpArr[2] := vals[1] - vals[2]*floor(p/q);
  end;

 Result := tmpArr;

end;

变量vals: TSolutions;在类中声明为私有(private),在构造函数中,我正在设置其长度。

我在docwiki上已经读到,动态数组是引用计数的,因此我不必担心它们的生命周期。可以肯定的是,我写过:
constructor TEuclidMod.Create;
begin

 SetLength(vals, 3);

end;

destructor TEuclidMod.Destroy;
begin

 vals := nil;
 inherited;

end;

到目前为止,这应该没问题; vals属于该类,在销毁该类时,我将其释放。那tmpArr呢?

我的功能正常工作。 tmpArr是本地的,然后我叫SetLength,我给了他一个长度:如果我没记错的话,这是在堆上创建数组。但是然后当我返回Result := tmpArr时,由于函数超出范围,它不会被删除(tmpArr)吗?我不想返回悬空的指针或其他东西!我需要确保它没有被释放。

我猜我很安全,因为它是一个函数并且返回TSolution,因此引用计数至少应始终为1。确切吗?基本上:即使它是本地的,也可以正确返回吗?

但是在这种情况下,根据我的发现
procedure test;
var a: TSolution;
begin

 SetLength(a, 7);
 //do something

end;

当过程超出范围时,a总是被释放!

最佳答案

动态数组是按引用计数的。不用担心它们的内存管理-只需使用它们即可;这就是引用计数的目的。您不必在析构函数中对类字段进行nil编码。销毁对象时,编译器将删除其引用计数。



好吧,不,因为您已经通过将数组分配给Result来返回该数组,并且大概是调用者还将结果分配给了一个新变量。除非调用者也未将函数结果分配给新变量,否则引用计数自然将至少保留一个。

10-08 17:15