Re: [ROOT] Removing TH1 from a list

From: Mike Kordosky (kordosky@mail.hep.utexas.edu)
Date: Fri Apr 06 2001 - 17:27:53 MEST


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