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