Re: [ROOT] Content of TList stored externally in TFile

From: cstrato (cstrato@aon.at)
Date: Tue Aug 20 2002 - 00:08:31 MEST


Dear Rene

Thank you for your tip. Sorrowly, I get a strange result, when
setting TList of TBaseClass to null. My constructors look as follows:

//--- MyClass -----------
class MyClass: public TNamed {
    TFile    *fFile;     //!
    TContent *fContent;  //!
    TList    *fTrash;

    void AddData()    {derivedClass->AddTree();}
    void UpdateData() {derivedClass->UpdateTree();}
    void DeleteData() {derivedClass->DeleteTree();}
}

MyClass::MyClass()
          :TNamed()
{
    if(kCS) cout << "---MyClass::MyClass(default)------" << endl;

    fFile      = 0;
    fContent   = 0;
    fTrash     = 0;

cout << "TClass::IsCallingNew()= " << TClass::IsCallingNew() << endl;
}//Constructor

MyClass::MyClass(const char *name, const char *title)
          :TNamed(name, title)
{
    if(kCS) cout << "---MyClass::MyClass------" << endl;

    fFile      = 0;
    fContent   = 0;
    fTrash     = new TList();
}//Constructor

//--- TBaseClass----------- (demo name of course)
class TBaseClass: public TNamed {
       TList  *fList;
       TList  *fTrash;

    void AddTree();
    void UpdateTree();
    void DeleteTree();
}

TBaseClass::TBaseClass()
          :TNamed()
{
    if(kCS) cout << "---TBaseClass::TBaseClass(default)------" << endl;

    fList  = 0;   //<===== problem when both TList set to = 0
    fTrash = 0;   //<===== problem when both TList set to = 0
//   fList  = new TList();
//   fTrash = new TList();

cout << "TClass::IsCallingNew()= " << TClass::IsCallingNew() << endl;
}//Constructor

TBaseClass::TBaseClass(const char *name, const char *title)
          :TNamed(name, title)
{
    if(kCS) cout << "---TBaseClass::TBaseClass------" << endl;

    fList  = new TList();
    fTrash = new TList();
}//Constructor

When I create either fList or fTrash or both in the default
constructor, then I have the problem that the second root session
contains the deleted objects.
However, when I set both fList = 0 and fTrash = 0 in the default
constructor, as you suggested, then my first root session is ok,
and I can check the root file with TBrowser. Interestingly, in my
second root session, where I delete trees and add new trees, I am
no longer able to open the root file with TBrowser, instead I get
a "*** Break *** bus error" after the output:
root [3] TBrowser b
root [4] ---TBaseClass::TBaseClass(default)------
TClass::IsCallingNew()= 1

What could be the reason for this behavior?

Thank you
Christian


Rene Brun wrote:

> Hi Christian,
> 
> My guess is that in the default constructor for your BaseClass
> (I hope your class is not called TBaseClass!) you set fContent
> to a non null value.
> The default constructor is called by ROOT I/O to create a dummy
> instance of your class to build the class dictionary or stream in
> an object from the file.
> 
> I suggest you add print statements in your BaseClass
> constructor/destructor to see what is happening.
> In your default constructor, you can test the return value
> of Bool_t TClass::IsCallingNew() to find out if your constructor
> is called by you or by ROOT I/O.
> 
> Rene Brun
> 
> 
> On Sun, 18 Aug 2002, cstrato wrote:
> 
> 
>>Dear Rooters
>>
>>I have a strange problem in a pretty complex program, where
>>I store TTrees in a TFile in one root session, but am also
>>able to add, delete or update trees in the next session.
>>The important classes compiled as library are:
>>class TContent: public TList {}
>>
>>class TBaseClass: public TNamed {
>>    void AddTree();
>>    void UpdateTree();
>>    void DeleteTree();
>>}
>>
>>class DerivedClass: public TBaseClass {}
>>
>>class MyClass: public TNamed {
>>    TFile    *fFile;
>>    TContent *fContent;
>>
>>    void AddData()    {derivedClass->AddTree();}
>>    void UpdateData() {derivedClass->UpdateTree();}
>>    void DeleteData() {derivedClass->DeleteTree();}
>>}
>>
>>First root session:
>>In a macro I call myClass->AddData(tree1). A tree is created in
>>fFile, and derivedClass1 is stored in fContent.
>>Assume that I have created three trees in this way, tree1, tree2
>>and tree3. When I call TBrowser, everything is perfectly ok.
>>
>>Second root session:
>>In a macro I call:
>>myClass->AddData(tree4)
>>myClass->DeleteData(tree1)
>>myClass->DeleteData(tree2)
>>myClass->AddData(tree5)
>>When I open fFile with TBrowser, tree4 and tree5 are added, and
>>their corresponding derivedClass4 and derivedClass5 is added to
>>fContent, while tree1 and tree2 are deleted and their corresponding
>>derivedClass1 and derivedClass2 are deleted from fContent, as
>>expected. So far everything is ok.
>>But now fFile contains suddenly the three derivedClass1,2,3 from
>>the first root session as single objects in fFile. Apparently,
>>the old content of fContent is read and stored in fFile.
>>I do not understand, why these objects are suddenly stored in
>>fFile, since I never call fFile->Write() but only obj->Write().
>>
>>The destructor of BaseClass looks as follows:
>>BaseClass::~BaseClass
>>{
>>    if (fFile) {
>>    // Write content to file only if new file or file is updated
>>       fFile->cd();
>>       if (fContent && (strcmp(fFile->GetOption(), "READ") != 0)) {
>>          // kSingleKey since fContent is a TCollection!!
>>          fContent->Write("", TObject::kSingleKey | TObject::kOverwrite);
>>       }//if
>>
>>       fContent->Delete();
>>       SafeDelete(fContent);
>>       SafeDelete(fFile);
>>    }//if
>>
>>//   fTrash->Delete();
>>    SafeDelete(fTrash);
>>}
>>
>>My questions are:
>>Can anybody give me a hint why the objects are written to fFile?
>>How can I prevent that the old list content is written to fFile?
>>
>>Thank you in advance for your help.
>>
>>Best regards
>>Christian
>>_._._._._._._._._._._._._._._._
>>C.h.i.s.t.i.a.n S.t.r.a.t.o.w.a
>>V.i.e.n.n.a       A.u.s.t.r.i.a
>>_._._._._._._._._._._._._._._._
>>
>>
>>
>>
>>
>>
>>
> 
> 
> 



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