【问题标题】:Delphi - How to free Memory from a TDataSet?Delphi - 如何从 TDataSet 中释放内存?
【发布时间】:2011-10-25 07:16:17
【问题描述】:

D2010,Win7 64 位。 你好,

我有一个 buttonClick 事件,需要处理在另一个例程中打开的 TDataSet... 获取数据库通用数据。

函数 GetDBGenericData 返回一个 TDataSet。该例程基本上采用 tQuery 组件,设置它的 SQL 属性,然后打开它。然后它将 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;

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

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

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

谢谢, GS

【问题讨论】:

    标签: delphi memory-leaks tdataset


    【解决方案1】:

    如果GetDBGenericData 为您的DS 变量分配了另一个TDataSet,您不应该使用CreateFree。您只是使用它来引用现有数据集。

    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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      相关资源
      最近更新 更多