我决定不使用一般的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
来返回该数组,并且大概是调用者还将结果分配给了一个新变量。除非调用者也未将函数结果分配给新变量,否则引用计数自然将至少保留一个。