Re: [ROOT] Problem with TObjectTable::Delete()

From: Mark Boulay (mboulay@lanl.gov)
Date: Wed Jan 30 2002 - 20:21:10 MET


Hello,
	I've included code for a small test class which illustrates my problem.
	Two files are included (ClassA.h and ClassA.C) which define and
implement
	ClassA, a simple class with a TH1F as a data member (fHistB).
	In CINT, I can load in the class definition (.L ClassA.C++), create
	a ClassA object and stream it to file without problem, with
	
	root [0] .L ClassA.C++
	root [1] ClassA A;
        root [2] TFile fout("test_file.root","RECREATE");
        root [3] A.Write("A");
        root [4] .q

	When I then read the object back from file, ie.

	root [0] .L ClassA.C++
	root [1] TFile fin("test_file.root","READ");
	root [2] ClassA *A = (ClassA *)fin.Get("A");

	and then quit root, I encounter the probem (segmentation violation
since
	fHistB is being deleted since there is a pointer to it in the
TObjectTable), 
	even though in the constructor for ClassA, the call is made to
fHistB.SetDirectory(0).

--Mark

Philippe Canal wrote:
> 
> Hi Mark,
> 
>       Originally, I had called B.SetDirectory(0) in
>         A's custom Streamer function, which worked, but I would prefer to use
>         the automatic Streamer.
> 
> You should probably call B.SetDirectory right after the creation of B
> (thus probably in A's constructor).
> 
> Cheers,
> Philippe.
> 
> -----Original Message-----
> From: owner-roottalk@pcroot.cern.ch
> [mailto:owner-roottalk@pcroot.cern.ch]On Behalf Of Mark Boulay
> Sent: Wednesday, January 30, 2002 12:33 PM
> To: Rene Brun
> Cc: roottalk@pcroot.cern.ch
> Subject: Re: [ROOT] Problem with TObjectTable::Delete()
> 
> Hi Rene,
>         Thanks for your reply.  Adding the call B.SetDirectory(0) in A's
> constructor
>         does not solve the problem.  Originally, I had called B.SetDirectory(0)
> in
>         A's custom Streamer function, which worked, but I would prefer to use
>         the automatic Streamer.
> 
>         Also, calling the static TH1::AddDirectory(kFALSE) works around the
>         problem, but I'd like to keep the ability to automatically add
>         histograms to the current directory.
> 
> --Mark
> 
> 
> Rene Brun wrote:
> >
> > Hi Mark,
> >
> > In the constructor of class A, you should add the following statement;
> >   B.SetDirectory(0);
> > By definition, A owns B. However the TH1F constructor (by default) will
> > add the created histogram to the list of objects in the current directory/file.
> > When the file is closed, this object is deleted. You will get the object
> > deleted twice.
> >
> > You can also turn off the feature adding automatically the histogram objects
> > to the current directory (gDirectory->GetList()) by calling the static function
> >   TH1::AddDirectory(kFALSE);
> > Note that if you do that, doing something like file->Write() will not
> > save your histograms to the file.
> >
> > Rene Brun
> >
> > Mark Boulay wrote:
> > >
> > > Hello,
> > >
> > >         I have a class (call it class A), derived from TObject which has as a
> > > data member a TH1F
> > >         (call it TH1F B).
> > >         When an object of class A is read in from file, and then the file
> > > closed,
> > >         a call is made to TObjectTable::Delete() deleting all objects which
> > > were
> > >         contained in the file.
> > >         The object A is first deleted, and then an attempt is made to delete B,
> > >         since a reference to it still exists in gObjectTable.  The problem
> > >         is that B has presumably already been deleted along with A, since it
> > >         is a data member of class A.
> > >
> > >         I'm using ROOT 3.02.07 under RH linux 7.2.
> > >
> > > Thanks in advance for assistance,
> > > Mark

#ifndef TEST_CLASSA_H
#define TEST_CLASSA_H

#include "TObject.h"
#include "TH1.h"

class ClassA : public TObject
{
 public:
  ClassA();
  ~ClassA();

 private:
  TH1F fHistB;
  ClassDef( ClassA, 1)

};

#endif





#include "ClassA.h"

ClassImp(ClassA)

  ClassA::ClassA()
{
  //Class A constructor.
  fHistB.SetDirectory(0);
}

ClassA::~ClassA(){;}



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:40 MET