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. 2, Do I need to declare fCurFile as static? 3, Why can I not use vMatrix(x,y) when TMatrix is created on the heap? (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