Hi Christian, On Wed, 3 Jan 2001 cstrato@EUnet.at wrote: > Dear Rene > > Thank you very much for answering my questions and showing me the problems > in my code, i.e. that vData of struct DATA has to be global. > (http://root.cern.ch/root/roottalk/roottalk01/0000.html) > > My goal is to implement the functions fillarray() and readarry() as member > functions of class MyClass which I want to use as library "libMyClass" in the > macro "Macro.C" shown below. Furthermore, I want to clone "vClassATree"to > "vDataTree", where I want to add a new branch and store this tree in a new > file (vDataFile)."vMyClass->Fill()" does already seem to work as expected, > but "vMyClass->Read()" results in a segmentation violation. > > I have the following questions: > > 1, A couple of objects are created in the member functions: TFile, TTree, TBranch. > When and how do I have to delete these objects? This is not quit clear to me. > You seem to use a complex logic for a simple problem. Anyhow, if you activate delete fCurFile; in your class destructor, the TFile and TTree object created in the Fill function will be deleted by the destructor. > 2, Do I need to declare fCurFile as static? NO > > 3, Why can I not use vMatrix(x,y) when TMatrix is created on the heap? I do not understand this point without having a working example. Rene Brun > (when used in a macro in a normal function it is possible) > I get the following error when compiling libMyClass: > [christian@cookiebook rootcode]$ gmake -f Makefile4MyClass > g++ -O -Wall -fPIC -fsigned-char -I/usr/X11/include -I/opt/root/include -c MyClass.cxx > > MyClass.cxx: In method `void MyClass::Fill(const char *, int)': > MyClass.cxx:143: `vMatrix' cannot be used as a function > > Thank you once again for your help. > > Best regards > Christian Stratowa > Vienna, Austria > > > /****************************************************************************** > * Macro.C * > ******************************************************************************/ > { > gROOT->Reset(); > gSystem->Load("/opt/rootcode/libMyClass.so"); > > MyClass *vMyClass = new MyClass("Test","Title","/opt/rootdata/DataFile.root", > "/opt/rootdata/FileA.root"); > > // clone tree from FileIn to FileOut and add new branch with text.txt > vMyClass->Fill("/opt/rootdata/text.txt"); > > // read tree from FileOut and print data > vMyClass->Read(0); > > // cleanup > delete vMyClass; > }//macro > > > /****************************************************************************** > * MyClass.h * > ******************************************************************************/ > #ifndef __MyClass__ > #define __MyClass__ > > #include etc > > typedef struct { > Float_t Meas; > Int_t x,y; > } DATA; > > DATA vData; //=====> should vData be declared static? > > class MyClass: public TNamed { > private: > TString fDataFileName; > TFile *fClassAFile; > TFile *fCurFile; > > public : > MyClass(){} > MyClass(const char *vName,const char *vTitle, > const char *vDataFileName,const char *vClassAFileName); > ~MyClass(); > void Fill(const char *vText); > void Read(Int_t vNum); > > ClassDef(MyClass,1) //MyClass > }; > > class ClassA: public TObject { > private: > variables > public : > ClassA(){} > ~ClassA(){} > Set, Get functions > > ClassDef(ClassA,1) //ClassA > }; > > #endif > > > /****************************************************************************** > * MyClass.cxx * > ******************************************************************************/ > #include etc > #include "MyClass.h" > > ClassImp(MyClass); > ClassImp(ClassA); > > //----------------------------------------------------------------------// > MyClass::MyClass(const char *vName,const char *vTitle, > const char *vDataFileName,const char *vClassAFileName): TNamed(vName,vTitle) > > { > fDataFileName = vDataFileName; > fClassAFile = 0; > fCurFile = 0; > > TFile *vClassAFile = new TFile(vClassAFileName,"READ"); > if (vClassAFile->IsOpen()) { > fClassAFile = vClassAFile; > } else { > exit(1); > }//if > }//Constructor > > //----------------------------------------------------------------------// > MyClass::~MyClass() > { > delete fClassAFile; //====>correct? or clone of vClassAFile? > // delete fCurFile; //====>?? > fCurFile = 0; > }//Destructor > > //----------------------------------------------------------------------// > void MyClass::Fill(const char *vText) > { > // TMatrix *vMatrix = new TMatrix(vNRows,vNCols); > TMatrix vMatrix(vNRows,vNCols); > > char vHeader[255]; > > ifstream vInput(vText, ios::in); > > while (1) { > vInput.getline(vHeader,255); > vName = &vHeader[0]; > > if (!vInput.good()) { > break; > }//if > > }//while > > // clone ClassAtree to copy ClassA to datatree > TTree *vClassATree = (TTree*)fClassAFile->Get("vTree"); > ClassA *vClassA = new ClassA(); > vClassATree->SetBranchAddress("vClassA",&vClassA); > > TFile *vDataFile; > if (gSystem->AccessPathName(fDataFileName)) { > vDataFile = new TFile(fDataFileName,"CREATE"); > } else { > vDataFile = new TFile(fDataFileName,"UPDATE"); > }//if > > if (vDataFile->IsOpen()) { > fCurFile = vDataFile; //===> should fCurFile be static? > } else { > exit(1); > }//if > > TTree *vDataTree = vClassATree->CloneTree(); > > TString vBranchName = "vDataBranch"; > // DATA vData; > TBranch *vDataBranch = vDataTree->Branch(vBranchName,&vData,"Meas/F:x/I:y"); > > // fill databranch > Int_t nentries = (Int_t)(vClassATree->GetEntries()); > // Int_t nentries = (Int_t)(vDataTree->GetEntries()); > for (i=0;i<nentries;i++) { > // vSCTree->GetEntry(i); > vDataTree->GetEntry(i); > > vInput >> x >> y >> Meas; > vData.Meas = Meas; > vData.x = x; > vData.y = y; > vMatrix(x,y) = Meas; //====> error when vMatrix = new TMatrix(); > > vDataBranch->Fill(); // code is incomplete, vMatrix is not stored > }//for > > vInput.close(); > > vDataFile->Write(); > > delete vClassA; > }//Fill > > //----------------------------------------------------------------------// > void MyClass::Read(Int_t vNum) > { > ClassA *vClassA; > // DATA vData; > > TFile *vFile = new TFile(fDataFileName); > TTree *vTree = (TTree*)vFile->Get("vTree"); > vTree->SetBranchAddress("vClassA",&vClassA); > vTree->SetBranchAddress("vDataBranch",&vData); > > Int_t nentries = (Int_t)(vTree->GetEntries()); > for (Int_t i=0;i<nentries;i++) { > vTree->GetEntry(i); > vX = vData.x; > vY = vData.y; > vMeas = vData.Meas; > printf("x=%8i,y=%8i,meas=%8f\n",vX,vY,vMeas); > }//for > }//Read > > > > Rene Brun wrote: > > > Hi Christian, > > > > 2- Why your program crashes ? > > ========================== > > You have a scope problem. In your function readarray, you set the > > branch address to a local struct. When you leave the scope of this > > function, > > this address becomes invalid. The browser reads at this invalid address. > > One simple solution is to declare your struct in the global scope as shown > > in the modified example below. > > > > Rene Brun > > >
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:33 MET