Page 1 of 1

Maybe memory leak when using DbcConnection.CreateStatement

Posted: 13.12.2005, 02:38
by codegen6797
Hi, all.

First let's say ZeosLib is a wonderfull product. I've been examining the code of the library and I'am a little bit confused. I want to use

Code: Select all

TZAbstractStatement
and

Code: Select all

TZAbstractResultSet
descendants in my application. The ZeosLib makes havy use
of interfaces.

The question:

Will the folowing code produce a memory leak.

Code: Select all

var
    FZConn:   TZConnection;
    FZStat:   IZStatement;
    FZResSet: IZResultSet;  

begin

  // create the database connection

  FZConn := TZConnection.Create(nil);
  FZConn.Properties.Text := ADBConnStr;
  FZConn.Connect;


  // create statement and execute query
  
  FZStat := FZConn.DbcConnection.CreateStatement;
  FZResSet := FZStat.ExecuteQuery(ASQL);

  
  //  do some processing
  ...some code...
  ...some code...

  // finally we can't realy destroy FZStat and FZResSet since they are
  // interfaces so we are left only with destroying the TZConnection

  FZConn.Disconnect;
  FZConn.Free;

end;
The comment:

From the library code it is obvious that

Code: Select all

TZConnection
instances adapt their selfs to the RDBMS system and

Code: Select all

FZConn.DbcConnection.CreateStatement
creates a
descendant of

Code: Select all

TZAbstractStatement
which is specific to the RDBMS.

Code: Select all

TZAbstractStatement
implements the

Code: Select all

IZStatement
interface. Now the problem is that the result from

Code: Select all

FZConn.DbcConnection.CreateStatement
is
an interface

Code: Select all

IZStatement
, rather then a reference to the created specific

Code: Select all

TZAbstractStatement
descendant instance. After using the interface you can
not dispose the allocated resources for the created statement instance since no link can be established from the interface to the statement (maybe I'am wrong here).
Everything would be ok if the

Code: Select all

TZConnection
instance kept track of all the statements it created and freed resources when needed (maybe using a GarbageCollector) but as much as I
can see it doesn't do that(maybe I'am wrong again).

another question:

Is there a way by which we can create a specific

Code: Select all

TZAbstractStatement
descendant
instances(specific to a RDBMS) and return a reference to that instance.
I know that I can do that the hard way by coding, checking
the protocol, but is there a faster way already implemented inside the library.


Thanks in advance. Looking forward to your answers.

Posted: 13.12.2005, 02:40
by codegen6797
Sorry about the bad formating. I thought that the code tags only bold and color
the text.

Posted: 13.12.2005, 19:26
by codegen6797
OK, I've figured it out. There is no memory leak here.
No wonder I could not see it using the debugging tools, since the code
that cleans the resources is in the System unit.

The TZAbstractResultSet, TZAbstractStatement are descendants of
TInterfacedObject. TInterfacedObject implements the IInterface
interface and counts the references to it's interface.
When the reference count hits zero the object is automatically
freed, so there is no need for cleanup code. See System unit.

Nice technique. Maybe it should be used more often by Object Pascal developers.