Re: [ROOT] Removing TH1 from a list

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Apr 06 2001 - 18:56:41 MEST


Hi Mike,

I have modified TH1::Streamer to take into account TH1::AddDirectory flag.
The change is in CVS. With this fix, you can do:

TIter next(list);
TKey* key;
TObject* obj;
TH1::AddDirectory(kFALSE);
        
while ( (key = (TKey*)next()) ){
        obj = key -> ReadObj(); // reads objects in from disk
        objvec.push_back(obj);
}


Mike Kordosky wrote:
> 
> Hi Rene,
> 
> Here is my point.
> 
> Say I do the following:
> {
> vector<TObject*> objvec;
> {
> TFile f("test.root");
> TList* list = f.GetListOfKeys();
> 
> if(!list) return 0; // no objects in .root file
> 
> TIter next(list);
> TKey* key;
> TObject* obj;
> 
> while ( (key = (TKey*)next()) ){
>         obj = key -> ReadObj(); // reads objects in from disk
> 
>         (f.GetList())->Remove(obj); //remove obj from current dir
> 
>         if( obj->InheritsFrom(TH1::Class()) ){// removing these lines
>                 ((TH1*)obj)->SetDirectory(0); // can cause a
>         }                                     // seg fault in ~TH1()
> 
>         objvec.push_back(obj);
> 
> }
> } //TFile f out of scope here, everything ok.
> purge(objvec); // removes objects
> } //objvec out of scope here
> 
> TH1 has a pointer called fDirectory. If you do
> not set this to zero, then in ~TH1() there can be a seg fault due to the
> lines:
> 
>    if (fDirectory) {
>       if (!fDirectory->TestBit(TDirectory::kCloseDirectory))
>          fDirectory->GetList()->Remove(this);
>    }
> 
> This comprises a rather special case, and I was wondering which are the
> other special cases. I look to the TObject class to provide the I/O
> interface, and when doing I/O I tend to manipulate objects using TObject
> member functions. For some classes, this is not enough. BTW, I did read
> the document on ownership prior to sending my comments.
> 
> mike
> 
> > Hi Mike,
> >
> > We posted a note at http://root.cern.ch/root/ObjectOwnership.pdf
> > as a response to several questions like yours. Please read this note.
> > I do not understand, in your case, why you want or have to make tests like
> >   IsA() == TXXX::Class() ?
> >
> > Rene Brun
> >
> > Mike Kordosky wrote:
> > >
> > > Hi,
> > >
> > > I wrote to this mailing list a month or so ago about removing TObjects
> > > from a file.  It was suggested that I do the following:
> > >
> > > // obj is preexisting and derived from TObject
> > >
> > > gDirectory->GetList()->Remove(obj);
> > >
> > > This does indeed remove the objects, so that when I close the file, they
> > > are not deleted.  However, there is an addtional snag. If my object
> > > derives from TH1, then when ~TH1() is eventually called, it looks at
> > > TH1::fDirectory.  If fDirectory != 0 , it tries to remove the object from
> > > its directory, (which doesn't exist). I know how to remove a histogram
> > > from a directory via TH1::SetDirectory(), but TH1 seems to be a very
> > > special case (along with TTree maybe?) where this is step is needed. Is
> > > there any way around this, besides lots of IsA ==
> > > TXXX::Class() statements?  If not, are there other classes that have
> > > similar caveats?
> > >
> > > mike kordosky
> >



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:41 MET