Oussaki
Oussaki

Reputation: 1649

Memory leaks when returning Tfields from a function

I just have a problem with Delphi that i'm about creating a function in my app and this function is like this

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;

the problem is I can't free the TMyquery from the out side of the function for that I have a problem of memory leaks and the application stop after 2 or 3 minutes later ....
but if I do free the TMyquery Object inside the function, then I can't get the function result from the outside of the function call.

Upvotes: 0

Views: 527

Answers (2)

Oussaki
Oussaki

Reputation: 1649

I just find another way maybe when I created an object without referenced it to a variable with a name that the memory manager can't fix the memory leak in this situation for that I created a Variable that have the same Type of function returning and in this case the memory manager can fix any memory leak with this named variable ....

this is the new code of the variable ...

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;

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 612993

You need to ensure that the TMyQuery object outlives the TFields object which it owns. But you must also make sure that you destroy that TMyQuery object to avoid the leak.

The simplest way is to return the TMyQuery object from the function and let the caller read the Fields property. When you are done, destroy the TMyQuery object. And naturally you'll use try/finally to ensure that exceptions don't lead to leaks.

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;

Upvotes: 6

Related Questions