D2: BDE memory leak using filters on TTable

Hi all,

I struggled with a memory leak problem. The problem was first reported by a
tech running a Beta of our product (developed using D2) on a Windows 95
system. I verified on my NT 3.51 development platform that the app is
indeed loosing memory.

Here is a description of the problem:
The following piece of code gets called repeatedly from a TTimer event:

        myTable.IndexFieldNames := 'DaTi';
        myTable.Filter := '(JType = 1) OR (JType = 2) OR (JType = 4)';
        myTable.Filtered := True;
        if (myTable.FindFirst) then
        begin
                GetThisRecord();
                myTable.Delete;
                Result := True;
        end
        else
                Result := False;
        myTable.Filtered := False;
        myTable.Filter := '';

For most of the time nothing is found, so the GetThisRecord() and
myTable.Delete part is hardly ever executed.
After running for several hours, the EDBEngine exception $2501
(Insufficient memory for this operation) is generated.

After investigation, I discovered that everytime the TTable.Filter property
is changed to a non-empty value, a call to BDE.DbiAddFilter is issued. When
changing the TTable.Filter property to an empty string, it is supposed to
issue a call to BDE.DbiDropFilter.  Due to the way the DB unit's code is
written, this does not happen if the TTable.Filtered property is False. The
exception eventually occurs in the DB unit at the point where yet another
DBE.BdiAddFilter call is issued.

So I've changed my code slightly to read:

        myTable.IndexFieldNames := 'DaTi';
        myTable.Filtered := True;
        myTable.Filter := '(JType = 1) OR (JType = 2) OR (JType = 4)';
        if (myTable.FindFirst) then
        begin
                GetThisRecord();
                myTable.Delete;
                Result := True;
        end
        else
                Result := False;
        myTable.Filter := '';
        myTable.Filtered := False;

A small change as you can see, but now the call to BDE.DbiDropFilter is
issued. This has cured the memory leak.

Incidentally, I tried demo versions of two de{*word*81} products and neither
detected this leak.

--
Abel du Plessis
abel...@unison.co.za
Kommetjie
South Africa