动态数组在超出作用域时是否自动取消分配?

16
在这个例子中。
procedure foobar;
var tab:array of integer;
begin
  setlength(tab,10);
end;

这个数组是被销毁了还是存在内存泄漏?


虽然它可能不会泄漏,但你确实应该释放自己的变量。
执行SetLength(tab,0); 这是额外的一行。
如果你担心这个问题,那么可以将其包装在try / finally块中。
- Vivian Mills
2
我不能支持那个建议,@Ryan。你也会手动清除所有字符串变量吗?当我看到代码将值分配给从未再次使用的变量时,这告诉我程序员并不真正理解语言的工作原理。特别是编译器已经在函数体周围放置了一个try-finally块,以确保动态数组变量得到清除。加入自己的块就过度了。 - Rob Kennedy
@Ryan,那是错误的。调用SetLength是完全浪费的,无论是在击键上还是在运行时的不必要的函数调用。动态数组由编译器管理,并且当它们超出范围时会自动释放。 - Ken White
2
数组的内存由编译器释放,但是如果使用动态数组引用对象数组,则仍然必须释放该数组所“拥有”的对象。将上述代码从“tab:整数数组”更改为“tab:TObject数组”,突然间就会出现泄漏的可能性。 - Warren P
1
@Ryan,将nil赋值、调用Finalize并将长度设置为零都是释放动态数组的等效方式。当数组超出范围时,它们都是不必要的,因为这是释放动态数组的另一种方式。帮助文档没有明确说明这一点,因为它通过说明动态数组使用与长字符串相同的引用计数技术来暗示了这一点。防御性编程很好,但最好是防御实际可能发生的事情。 - Rob Kennedy
显示剩余3条评论
2个回答

16

内存已被释放。(也就是说,没有内存泄漏!)


4
如果编译器管理了元素(比如动态数组、字符串、接口、带有这些类型的记录等),它们也会被释放。 - alex
2
对于“tab:整数数组”,所有内容都会被释放。但是对于“tab:TObject数组”或任何其他类,您必须自己释放对象。 - Warren P
没错,@Warren,但这与数组无关。同样的建议适用于普通标量。对象需要被释放;整数不需要。 - Rob Kennedy

1
数组会自动释放,但我曾经遇到过一些不明原因导致它没有被释放的情况。我通过将数组设置为nil来解决这个问题。

6
只有两个原因会导致它无法被释放。一个是你在指针上做了一些可怕的事情,破坏了引用计数;另一个是数组归某个对象或记录所有,并且该对象也存在泄漏问题。 - Mason Wheeler
我知道,不知何故还有其他原因导致它无法自动释放。真希望我还有那个例子来证明!但是我没有了。 - Alan Clark
那可能是编译器代码生成中的一个错误。或者可能是一个线程变量?帮助文档明确指出,作为线程变量使用的托管类型不会自动释放,需要手动释放。 - Ken Bourassa
这不是一个线程变量,我从未使用过它们。它只是一个双精度数组,是一个类的字段,FastMM揭示了泄漏。这是在Delphi 7中发生的。 - Alan Clark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接