Delphi 从函数返回Tfields时内存泄漏

Delphi 从函数返回Tfields时内存泄漏,delphi,memory,memory-leaks,Delphi,Memory,Memory Leaks,我只是对Delphi有一个问题,我想在我的应用程序中创建一个函数,这个函数是这样的 function Get_Foundation_infos(): TFields; begin with TMyQuery.Create(nil) do begin try Connection := DataBaseForm.DataBaseForm1.DataBase; SQL.Add('SELECT * FROM `foundation_infos` WHERE `I

我只是对Delphi有一个问题,我想在我的应用程序中创建一个函数,这个函数是这样的

function Get_Foundation_infos(): TFields;
begin
  with TMyQuery.Create(nil) do
  begin
    try
      Connection := DataBaseForm.DataBaseForm1.DataBase;
      SQL.Add('SELECT * FROM `foundation_infos` WHERE `Id`=1');
      Execute;
      Result := Fields;
    except
      on E: Exception do
        Result := nil;
    end;
  end;
end;
问题是我无法从函数的外侧释放
TMyquery
,因为我存在内存泄漏问题,应用程序会在2或3分钟后停止……

但是如果我在函数内部释放
TMyquery
对象,那么我就无法从函数调用外部获得函数结果

您需要确保TMyQuery对象比它拥有的TFields对象更有效。但您还必须确保销毁该TMyQuery对象以避免泄漏

最简单的方法是从函数返回TMyQuery对象,并让调用方读取Fields属性。完成后,销毁TMyQuery对象。当然,您将使用try/finally来确保异常不会导致泄漏

function CreateFoundationQuery: TMyQuery;
begin
  Result := TMyQuery.Create(nil);
  try
    Result.Connection := DataBaseForm.DataBaseForm1.DataBase;
    Result.SQL.Add('SELECT * FROM `foundation_infos` WHERE `Id`=1');
    Result.Execute;
  except
    Result.Free;
    raise;
  end;
end;

您需要确保TMyQuery对象比它拥有的TFields对象更有效。但您还必须确保销毁该TMyQuery对象以避免泄漏

最简单的方法是从函数返回TMyQuery对象,并让调用方读取Fields属性。完成后,销毁TMyQuery对象。当然,您将使用try/finally来确保异常不会导致泄漏

function CreateFoundationQuery: TMyQuery;
begin
  Result := TMyQuery.Create(nil);
  try
    Result.Connection := DataBaseForm.DataBaseForm1.DataBase;
    Result.SQL.Add('SELECT * FROM `foundation_infos` WHERE `Id`=1');
    Result.Execute;
  except
    Result.Free;
    raise;
  end;
end;

我只是找到了另一种方法,可能是当我创建一个对象时,没有引用一个名为的变量,内存管理器无法修复这种情况下的内存泄漏,因为我创建了一个具有相同类型函数返回的变量,在这种情况下,内存管理器可以用这个名为的变量修复任何内存泄漏

这是变量的新代码

function Get_Foundation_infos(): TMyQuery;
var
  q: TMyQuery;
begin
  q := TMyQuery.Create(nil);

  with q do

  begin

    try

      Connection := DataBaseForm.DataBaseForm1.DataBase;

      SQL.Add('SELECT * FROM `foundation_infos` WHERE `Id`=1');
      Execute;

      Result := q;

    except
      on E: Exception do
        Result := nil;
    end;

  end;

end;

我只是找到了另一种方法,可能是当我创建一个对象时,没有引用一个名为的变量,内存管理器无法修复这种情况下的内存泄漏,因为我创建了一个具有相同类型函数返回的变量,在这种情况下,内存管理器可以用这个名为的变量修复任何内存泄漏

这是变量的新代码

function Get_Foundation_infos(): TMyQuery;
var
  q: TMyQuery;
begin
  q := TMyQuery.Create(nil);

  with q do

  begin

    try

      Connection := DataBaseForm.DataBaseForm1.DataBase;

      SQL.Add('SELECT * FROM `foundation_infos` WHERE `Id`=1');
      Execute;

      Result := q;

    except
      on E: Exception do
        Result := nil;
    end;

  end;

end;

我会让使用字段的人创建并释放查询。字段与查询相关,您无法释放查询并使用字段。Sertac意味着调用方创建查询,然后调用传递查询对象的函数。然后对表单执行函数,执行查询并返回。然后打电话的人戳了戳田地。最后,调用方破坏查询。这不是使用函数的最佳实践,如果我返回任何问题,我将尝试您的方法。。。谢谢同志们。请用“伙计们”而不是“同志们”,否则你可能会被误解。我会让使用字段的人创建并释放查询。字段与查询相关,因此你不能释放查询并使用字段。Sertac意味着调用方创建查询,然后调用传递查询对象的函数。然后对表单执行函数,执行查询并返回。然后打电话的人戳了戳田地。最后,调用方破坏查询。这不是使用函数的最佳实践,如果我返回任何问题,我将尝试您的方法。。。谢谢同志们。请用“伙计们”而不是“同志们”,否则你可能会被误解。这和我的答案一样,只是在创建查询后出现异常时,你的代码会泄漏。是的,我必须免费拨打电话;当出现异常时。@David:这段代码使用了一个不必要的
q
变量,而您的变量没有。函数应该以
Create
开始,遵循一个有用的约定,向所有者表明他有责任销毁该对象。这与我的回答相同,除非你的代码在创建查询后出现异常时泄漏。是的,我必须调用免费的;当出现异常时。@David:此代码使用了一个不必要的
q
变量,而您的变量没有。函数应该以
Create
开始,遵循一个有用的约定,向所有者表明他有责任销毁该对象。