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

时间:2011-10-24 23:11:43

标签: delphi memory-leaks tdataset

D2010,Win7 64bit。 您好,

我有一个buttonClick事件需要处理在另一个例程中打开的TDataSet ... GetDBGenericData。

函数GetDBGenericData返回一个TDataSet。这个例程基本上采用一个tQuery组件,设置它的SQL属性,然后打开它。然后它将TDataSet返回到我的按钮。

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;

我的问题是 - 了解DS。 我在这个例程中创建它。我将它“分配”到指向组件的TDataSet。如果我不释放它,我有内存泄漏(如EurekaLog报道)。 如果我释放它,我下次运行这个例程时会得到一个AV。 (特别是在GetDBGenericData例程中)。

我认为发生的事情是DS被分配给(而不是复制)到正在返回的TDataSet,所以实际上,我在这个例程中释放了两个DS,并且在GetDBGenericData中使用了tQuery,当我做一个免费的。

如何“中断”链接,然后删除与我动态创建的内存关联的内存。

谢谢, GS

1 个答案:

答案 0 :(得分:4)

如果DS变量被TDataSet分配给GetDBGenericData另一个Create,则您不应Freeprocedure 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; 。您只是用它来引用现有数据集。

{{1}}