Bug in TClonesArray::Streamer

From: Andy Salnikov (AASalnikov@lbl.gov)
Date: Tue Aug 24 1999 - 17:32:34 MEST


  Hi all,

  yesterday I had a "fun" time, trying to make things work while writing
and reading data in the TTrees. Basically, I needed a collection of
items to be saved as a single object (branch) in the tree. I thought to
use a TClonesArray as a persistent collection, 'cause everyone says that
TClonesArray is superb. Fine. The first thing which I encountered was
that an advertised TTree:Branch("branch",&clonesPtr,xxx,0) for
TClonesArray does not seem to work at all when the splitlevel is zero.
The branch is not get created (at least not in the tree). Is it expected
to be that way? I solved this switching to BranchObject, calling
TTree::Branch("branch","TClonesArray",&clonesPtr,xxx,0). That seemed to
work, but I have been caught by the TTree::Print() output. It gave me
something like that:

************************************************************************
******
*Tree    :testStream: ROOT output stream
*
*Entries :     1000 : Total  Size =    257352 bytes  File  Size =
38796 *
*        :          : Tree compression factor =   6.63
*
************************************************************************
******
*Branch  :objectBranch : objectBranch
*
*Entries :     1000 : Total  Size =         0 bytes  File Size  =
0 *
*Baskets :        0 : Basket Size =     32768 bytes  Compression=   1.00
*
*.......................................................................
.....*
*Branch  :listBranch : listBranch
*
*Entries :     1000 : Total  Size =    257352 bytes  File Size  =
38796 *
*Baskets :        8 : Basket Size =     32768 bytes  Compression=   6.63
*
*.......................................................................
.....*

The first branch seem to have no data at all. That scared me a bit and I
have spend more time trying to figure out what's wrong with my code. I
should not have done it, cause the data were actually there, only the
output was misleading. Increasing number of event 10 times I got the
expected output:

************************************************************************
******
*Tree    :testStream: ROOT output stream
*
*Entries :    10000 : Total  Size =   2861280 bytes  File  Size =
434051 *
*        :          : Tree compression factor =   6.59
*
************************************************************************
******
*Branch  :objectBranch : objectBranch
*
*Entries :    10000 : Total  Size =    255591 bytes  File Size  =
40183 *
*Baskets :        9 : Basket Size =     32768 bytes  Compression=   6.36
*
*.......................................................................
.....*
*Branch  :listBranch : listBranch
*
*Entries :    10000 : Total  Size =   2605689 bytes  File Size  =
393868 *
*Baskets :       81 : Basket Size =     32768 bytes  Compression=   6.62
*
*.......................................................................
.....*

More serious problem was awaiting me when I tried to read back what I
have saved. I got an immediate crash when I tried to read the branch
with the TClonesArray (created as above, in a single branch with
splitlevel=0). After few hour spent in the debugger, I came to what I
think is a bug in the TClonesArray code. The TClonesArray::Streamer()
executes the following two lines:

         fKeep  = new TObjArray(nobjects);
         Expand(nobjects);

Expand(), when "nobjects" is less than fSize (and this is the case),
tries to delete the items [nobjects,fSize-1] from fKeep. And it crashes,
just as anyone would expect, 'cause there are no allocated elements in
fKeep behind "nobjects". My guess is that this must be fixed, but I
myself cannot propose any fix, it look a bit complicated stuff for me.
BTW, what is the design issue behind TClonesArray "being" and TObjArray
and "having" TObjArray" at the same time. Is not this unnecessary
complication of the design?

  Cheers,
  Andy.



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:38 MET