inheriting from TClonesArray

Jiri Masik (masik@nc25.troja.mff.cuni.cz)
08 Jun 1998 14:58:19 +0200


Hello,
I've defined a class called Tracks which inherits from
TClonesArray. It's a collection of Track objects and extends the
functionality of TClonesArray by jet algorithms, display methods etc.
In my Event class I have pointers to several Tracks objects. The event
class constructor allocates every time new Tracks object via fTracks =
new Tracks(); which is deleted in Event destructor by delete fTracks.
Everything seems to work fine when I create event object and
add tracks to it. upon deletion of the event object also the Tracks
object and the contents of the collection are destroyed. When I check
in gObjectTable afterwards, there's nothing left from my
Event/Tracks/Track objects.
The problem is that when I use tree->GetEvent() to read events
back from a file, there's a memory leak which prevents me from
analysing larger data volumes. there is one Tracks object per event
left in the gObjectTable. When I replace pointer to Tracks object in
the event class by pointer to TClonesArray I don't observe any memory
deallocation problems so I guess the problem comes from my Tracks
class.
I also tried a scenario similar to the example coming with
Root - to call new Tracks() only first time when event object is
created and call Delete method of TClonesArray when Track objects are
not needed anymore but the behaviour is the same - again Tracks
objects left.
Please my questions are whether it is ok to put derived
objects from TClonesArray in a TTree and how should I write proper
constructor/destructor for such a class.

thank you in advance for your help.

Jiri

////////////////////////////////////////////////////////////
class Tracks : public TClonesArray {
private:
Int_t fNtrack;

public:
Tracks();
Tracks(Int_t size);
~Tracks();
void AddTrack(Float_t x,Float_t y,Float_t z,Float_t e,Float_t m,Int_t ch);
Track* Get(Int_t index);
void Print() const;

ClassDef(Tracks,1)
};

////////////////////////////////////////////////////////////
Tracks::Tracks()
:TClonesArray("Track",32, kFALSE){
fNtrack = 0;
}

Tracks::~Tracks(){
cout << "<T\n";
}

void
Tracks::AddTrack(Float_t x,Float_t y,Float_t z,Float_t e,Float_t m,Int_t ch){
Tracks &tracks = *this;
new(tracks[fNtrack++]) Track(x,y,z,e,m,ch);
}

////////////////////////////////////////////////////////////
class Event : public TObject {

public:
Int_t fNtrack;
EventHeader fEvtHdr;
Tracks *fTracks;

public:
Event();
~Event();
void Clear(Option_t *option ="");
void SetHeader(Int_t i, Int_t run, Int_t date, Float_t bm);
void AddTrack(Float_t x,Float_t y,Float_t z,Float_t e,Float_t m,Int_t ch);
EventHeader *GetHeader() { return &fEvtHdr; }
Tracks *GetTracks() { return fTracks; }

ClassDef(Event,1) //Event structure
};