[英]Delphi - How to free Memory from a TDataSet?
D2010, Win7 64bit. D2010,Win7 64位。 Hello, 你好,
I have a buttonClick event with needs to process a TDataSet opened in another routine... GetDBGenericData. 我有一个buttonClick事件,需要处理在另一个例程中打开的TDataSet ... GetDBGenericData。
The function GetDBGenericData returns a TDataSet. 函数GetDBGenericData返回一个TDataSet。 This routine basically takes a tQuery component, sets it's SQL property, and opens it. 这个例程基本上使用一个tQuery组件,设置它的SQL属性,然后打开它。 It then returns the TDataSet to my buttonclick. 然后将TDataSet返回给我的buttonclick。
procedure TForm1.Button2Click(Sender: TObject);
var
DS : TDataSet;
begin
DS := TDataSet.Create(nil);
DS := GetDBGenericData(dbSOURCE, 'LIST_ALL_SCHEMAS', [] );
while Not DS.EOF do
begin
ShowMessage(DS.FieldByName('USERNAME').AsString);
DS.Next;
end;
DS.Close;
DS.Free;
My problem is -- Understanding DS. 我的问题是-了解DS。 I am creating it here in this routine. 我在此例程中在这里创建它。 I am "assigning" it to a TDataSet that points to a component. 我将其“分配”到指向组件的TDataSet。 If I DON'T Free it, I have a memory leak (as reported by EurekaLog). 如果我不释放它,则会发生内存泄漏(由EurekaLog报告)。 If I do free it, I get an AV the next time I run this routine. 如果我释放它,则下次运行此例程时会得到AV。 (specifically inside the GetDBGenericData routine). (特别是在GetDBGenericData例程中)。
What I think is happening is that DS is getting assigned to (as opposed to copying) to the TDataSet that is being returned, so in effect, I am FREEING BOTH DS in this routine, and the tQuery in GetDBGenericData, when I do a free. 我认为正在发生的事情是将DS分配给(而不是复制)到要返回的TDataSet,所以实际上,当我执行免费操作时,我将在此例程中同时释放DS和GetDBGenericData中的tQuery 。
How do I "break" the linkage, and then delete the memory associated to ONLY the one I am dynamically creating. 如何“断开”链接,然后删除仅与我动态创建的内存关联的内存。
Thanks, GS 谢谢,GS
If your DS
variable is being assigned another TDataSet
by GetDBGenericData
, you should neither Create
or Free
it. 如果GetDBGenericData
为您的DS
变量分配了另一个TDataSet
, GetDBGenericData
不应Create
或Free
它。 You're just using it to refer to an existing dataset. 您只是使用它来引用现有数据集。
procedure TForm1.Button2Click(Sender: TObject);
var
DS : TDataSet;
UserNameField: TField; // Minor change for efficiency
begin
DS := GetDBGenericData(dbSOURCE, 'LIST_ALL_SCHEMAS', [] );
// Call FieldByName only once; no need to create or
// free this either.
UserNameField := DS.FieldByName('USERNAME');
while not DS.Eof do
begin
ShowMessage(UserNameField.AsString);
DS.Next;
end;
// I'd probably remove the `Close` unless the function call
// above specifically opened it before returning it.
DS.Close;
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.