当在函数和函数中创建的对象完成时,如果未明确销毁对象会发生什么?
当所有变量超出范围时是否需要销毁,或者当它们超出范围时是否需要处理?
那么,例如,在调用custom_function之后locallist会发生什么?
function TForm1.custom_function(string: test_string): boolean; var locallist: TStringList; begin locallist := TStringList.Create; // do a bunch of stuff here, but don't destroy locallist return true; end;
Ray.. 16
你会得到内存泄漏.
正确的模式是
myObject := TObject.Create; try //do stuff finally myObject.Free; end;
此外,如果您需要稍后测试该对象是否已被释放,则使用FreeAndNil(myObject).它也会将变量设置为nil,因此您可以稍后进行测试.
你会得到内存泄漏.
正确的模式是
myObject := TObject.Create; try //do stuff finally myObject.Free; end;
此外,如果您需要稍后测试该对象是否已被释放,则使用FreeAndNil(myObject).它也会将变量设置为nil,因此您可以稍后进行测试.
正如其他海报所指出的那样,需要明确释放这些对象.这通常是通过使用try..finally块手动完成的,如Ray所示.但是,您应该注意到例外情况.
组件(TComponent descendants)将Owner参数传递给它们的构造函数.如果所有者不是nil,则所有者组件将获得新组件的所有权,并在获取时释放它.这就是为什么你不必清理自己的表格; 它们连接到Application对象,它知道如何在程序完成时释放自己.但是,如果在运行时创建组件,则需要为其指定所有者或将nil传递给构造函数,然后自行释放它. 不要通过将组件与所有者释放来混合两者. 在某些情况下,这可能导致双重自由条件.
实现引用计数的接口对象(主要是TInterfacedObject后代)如果将它们专门用作接口(而不是对象),则由引用计数机制释放.当删除对它们的最后一个接口引用时,它们会自动释放.如果已将TInterfacedObject分配给接口引用,请不要手动释放它.这将引发异常.此外,请注意,并非所有带接口的对象都实现引用计数.通常只是来自TInterfacedObject的那些.
创建一个对象,使用try..finally块,然后释放它并不总是切实可行.有时这对你正在做的事情不起作用,特别是如果你将对象分配给某种列表(并且制作了很多它们.)在这种情况下,使用TObjectList是个好主意(或者更好的是,如果你有D2009,一个TObjectList),其OwnsObjects属性设置为true.这会导致列表成为其中对象的所有者,并在释放时释放它们,就像组件一样.同样,如果对象属于对象列表,则不要手动释放对象.
动态数组(包括字符串)由编译器使用引用计数系统进行管理,并且大多数其他类型的变量在堆栈上分配.你永远不必担心手动释放除了对象以外的任何东西,除非你正在玩指针.
这可能听起来很复杂,但你很快就会习惯它.请记住,每个对象都由以下三种内容之一拥有:另一个对象,接口引用计数系统或您的代码,并且所有者应在不再需要时释放所有对象.什么都不应该试图释放其他东西所拥有的东西.(你不应该偷.)记住这些指导方针,你最终会得到良好的记忆管理.您还可以在DPR的主例程中设置"ReportMemoryLeaksOnShutdown:= true"以获得更多帮助.
它变成了泄露的记忆.
您通常应该围绕这样的分配:
locallist := TStringList.Create; try // work with locallist here finally locallist.Free; end;
Delphi中唯一一种在超出范围时有自杀倾向的引用是接口引用.