简体   繁体   English

Delphi-如何从TDataSet中释放内存?

[英]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变量分配了另一个TDataSetGetDBGenericData不应CreateFree它。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM