以下有关Delphi中动态数组的文章说,您可以使用SetLength()
函数分配动态数组。
myObjects : array of MyObject;
...
SetLength(myObjects, 20);
// Do something with the array.
myObjects := nil;
http://delphi.about.com/od/beginners/a/arrays.htm
对我来说,这似乎是内存泄漏:
问题是,如果SetLength()
等效于C ++ MyObject *obs = new MyObject[20]
,那么数组只是指针,那么将DelphimyObjects
变量nil
设置为obj = NULL
与C ++中的设置相同吗?即,这是内存泄漏吗?
编辑:我从戴维的答案中了解到,编译器为动态分配的数组管理内存。我也从他的回答理解比编译器管理的普通类实例存储(因此使用myObj := MyObject.Create
和myObj.Free
,myObj := nil
等)。另外,由于Delphi类(而非记录)总是分配在堆上(Delphi使用一种引用/指针系统),这是否意味着(自动内存管理的)动态数组中的所有对象仍然需要内存,由我管理?例如,以下内容是否会由于两次释放结果而导致故障?
myObjects : array of MyObject;
...
SetLength(myObjects, 20);
for i := 0 to 19 do
begin
myObjects[i] := MyObject.Create;
end;
// Do something with the array.
// Before de-allocating it, if I *know* I am the only user of the array,
// I have to make sure I deallocate each object.
for i := 0 to 19 do
begin
myObjects[i].Free;
myObjects[i] := nil; // Redundant, but for illustrative purposes.
end;
myObjects := nil;
动态数组由编译器管理。这是通过维护对数组的所有引用的引用计数来完成的。分离对数组的最后一个引用后,将释放该数组。
该文档说:
动态数组变量是隐式指针,并通过与长字符串相同的引用计数技术进行管理。要取消分配动态数组,请将nil分配给引用该数组的变量,或者将该变量传递给Finalize。如果没有其他引用,则这两种方法均可处理该数组。当动态数组的引用计数降至零时,它们会自动释放。长度为0的动态数组的值为nil。不要将取消引用运算符(^)应用于动态数组变量,也不要将其传递给New或Dispose过程。
在您的示例中,将nil
变量分配给唯一的引用将导致数组被释放。因此没有泄漏。
Delphi动态数组与C ++有很大不同new
。与Delphi中最接近的类似是使用GetMem
或分配原始内存New
。
您的编辑提出了另一个问题。不管理类的实例。必须明确释放它们。您的代码可以做到这一点。没有双重释放,因为编译器不管理类的实例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句