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

发布于 2024-12-11 20:09:21 字数 821 浏览 0 评论 0原文

D2010,Win7 64位。 您好,

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

函数 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,因此实际上,当我执行 free 操作时,我将释放此例程中的 DS 以及 GetDBGenericData 中的 tQuery 。

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

谢谢, GS

D2010, Win7 64bit.
Hello,

I have a buttonClick event with needs to process a TDataSet opened in another routine...
GetDBGenericData.

The function GetDBGenericData returns a TDataSet. This routine basically takes a tQuery component, sets it's SQL property, and opens it. It then returns the TDataSet to my 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.
I am creating it here in this routine. I am "assigning" it to a TDataSet that points to a component. If I DON'T Free it, I have a memory leak (as reported by EurekaLog).
If I do free it, I get an AV the next time I run this routine. (specifically inside the GetDBGenericData routine).

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.

How do I "break" the linkage, and then delete the memory associated to ONLY the one I am dynamically creating.

Thanks,
GS

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一生独一 2024-12-18 20:09:21

如果 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;

If your DS variable is being assigned another TDataSet by GetDBGenericData, you should neither Create or Free it. 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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文