Re: inheriting from TClonesArray

Rene Brun (Rene.Brun@cern.ch)
Tue, 09 Jun 1998 10:42:01 +0200


Jiri,
There is nothing wrong in creating a class deriving from
TClonesArray. From your description below, I assume that you are
creating a TTree with one branch referencing one event object.
You must proceed like in $ROOTSYS/test/Event. Make sure that the
the TClonesArray is created only once. In our example,
we use a global pointer gTracks. In the Event constructor, we simply
set the pointer fTracks to point to gTracks.
It would be better to have a Run class with a member fTracks
and in the Event constructor to point to this object.

Rene Brun

>
> 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
> };