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