Free
代码块,例如在finally
块中。...
finally
a.Free;
b.Free;
c.Free;
end;
此代码假定Free
永远不会引发异常,因为如果a.Free
引发了异常,那么b
和c
的内存将被泄漏。这个假设是否合理?
Free
代码块,例如在finally
块中。...
finally
a.Free;
b.Free;
c.Free;
end;
此代码假定Free
永远不会引发异常,因为如果a.Free
引发了异常,那么b
和c
的内存将被泄漏。这个假设是否合理?
Free
方法本身并不会显式地引发异常,但它调用虚析构函数 Destroy
,而该函数可能会引发异常。
因此,如果您想确保所有对象都被销毁,即使其中一个析构函数引发异常,您最终会得到像这样的代码:
a := TMyObject.Create;
try
b := TMyObject.Create;
try
...
finally
b.Free;
end;
finally
a.Free;
end;
尽管如此,在设计上应该遵循一项原则,即不要在析构函数中引发异常。所以,在我看来,如果在析构函数中引发了异常,那么你的程序基本上已经出了问题。此时泄漏对象并不是什么值得担心的事情。如果您的析构函数引发了异常,那么您可能已经泄漏了,因为该析构函数未能完成。
所以,在我看来,将一些调用Free
的操作组合在一起也是完全合理的,并且当然要避免深度嵌套的try
/finally
语句,这值得努力实现。
如果您只想使用一个try
/finally
语句,请记住编写以下代码:
a := nil;
b := nil;
try
a := TMyObject.Create;
b := TMyObject.Create;
...
finally
b.Free;
a.Free;
end;
在我的代码库中,我有一些辅助方法可以让这个过程更加简洁。那么代码看起来就像这样:
InitialiseNil(a, b);
try
a := TMyObject.Create;
b := TMyObject.Create;
...
finally
FreeAndNil(b, a);
end;
我把我的FreeAndNil
函数命名为SysUtils
中的同名函数,乍一看可能有点奇怪,但这样做是安全和良性的。当你有两个以上的对象时,这些辅助函数自然而然地发挥作用。
取决于析构函数中发生了什么。
导致SomeObj.Free
引发异常的原因可能有两个:
SomeObj
实例或其祖先类的析构函数中未处理的异常。SomeObj
,导致无效的类引用。在您的情况下,如果a.Free
由于上述任何原因引发异常,则对象b
和c
将会存在内存泄漏,并且可能由于析构函数中未处理的异常而导致对象a
中的一些泄漏。
如果你的a.free引发了异常,那么a(根据析构函数从a对象字段中释放了多少), b和c对象将会泄漏,因为执行将被中断。无论如何,如果析构函数引发错误,则说明代码存在问题。因此,你应该使用try..finally块来保护代码,但在我看来,你应该验证析构函数在任何情况下都不会出现错误。
a
对象的析构函数抛出异常,它也会泄漏。 - user743382a
将会一直泄漏,因为a
本身的内存肯定不会被释放,但你指出它的某些子对象可能会被释放是正确的。 - user743382std::terminate
),所以我做出了(事实上是无效的)假设,认为在Delphi中也是这样的情况。 - Stuart Golodetz当然,FREE可能会引发异常 - 因此,如果A.FREE引发异常,则您的代码将泄漏内存,B.FREE和C.FREE将不会被调用。
问题是,您想处理这些异常还是让它们发生?这将取决于您的代码将用于什么,其他开发人员是否将使用它(例如)。为了防止任何内存泄漏,您应该嵌套try..finally部分;
a:=tobject.create;
try
b:=tobject.create;
try
c:=tobject.create;
...
finally
c.free;
end;
finally
b.free;
end;
a.free;
这是一种情况。关键在于您的代码实际上正在做什么,以确定是否应该在try..finally部分中包装A.FREE,尽管我猜您可能应该这样做。
a.free;
不在任何 try
..finally
块中,如果 b:=tobject.create;
抛出异常(同样适用于 c
),你尝试释放 b
。 - user743382c.free
引发异常,你仍然会有一个泄漏,因为你实际上没有释放 c
。 - user743382a.free;
周围加上 try
..finally
。如果你绝对确定代码永远不会引发异常,那么你就不需要它,但是你也不需要包含任何你已经包含的 try
..finally
。 - user743382