Hi Benoit,
The main problem in your test was that you delete the TClonesArray
in the Gentest destructor and you do not reset the static gtca.
I have recoded/simplified your example. See attachement
untar test.tar.gz
run the 3 lines script go
root -b -q test.C
root macro.C
Rene Brun
Benoit Revenu wrote:
>
> Hi !
>
> I meet some problems when I use a TClonesArray made upon a derived class.
>
> These are the different step I follow :
> ---------------------------------------
> 1. create an instance of the class Test, derived from GenTest (derived
> from TObject). files class.h and class.cc
> 2. Construct a TClonesArray based on this instance of Test (class.cc)
> 3. Create a TTree and one branch based on an instance of Test (test.cc)
> 4. make a test program run and fill the tree, then writing a root file
> (test.cc)
> 5. I launch root interactive and I use a TChain to read the TTree
> contained in the root file (macro.cc)
> 6. make some plots of variable contained in the Test, itself contained in
> the TClonesArray ====> NO PROBLEM !
> 7. just add another root file of the same format and same data to the
> existing TChain (->Add("file.root")) and impossible to make plots of
> the variables contained in the TClonesArray.
>
> This problem seems to exist only with this derived class. If the class
> Test only derive from TObject, then there are no problems.
>
> Any idea ???
>
> ---------------------------------------------------------------------------
> these are the files :
> ---------------------
> ##############################
> # class.h #
> ##############################
> #ifndef CLASSH
> #define CLASSH
>
> #include "TClonesArray.h"
> #include <iostream>
>
> class Truc : public TObject
> {
> public:
> Truc(double b=-1){a=b;}
> ~Truc(){}
> double a;
> ClassDef(Truc,1)
> };
>
> class GenTest : public TObject
> {
> public:
> GenTest(unsigned int=0);
> virtual ~GenTest();
> TClonesArray *tca;
> Int_t Nstat;
> Int_t totNstat;
> void AddTruc(double);
> void Clear();
> ClassDef(GenTest,1)
> };
>
> class Test : public GenTest
> {
> public:
> Test();
> virtual ~Test();
> static TClonesArray *gtca;
> ClassDef(Test,1)
> };
>
> #endif
>
> #############################
> # class.cc #
> #############################
> #include "class.h"
>
> ClassImp(GenTest)
> ClassImp(Test)
> ClassImp(Truc)
>
> GenTest::GenTest(unsigned int address)
> {
> if( address == 0x0 )
> {
> tca = new TClonesArray("Truc",10);
> }
> Nstat = 0;
> totNstat = 0;
> }
>
> GenTest::~GenTest()
> {
> cout << "~GenTest()" << endl;
> Clear();
> if( tca != NULL ) delete tca;
> }
>
> void GenTest::AddTruc(double a)
> {
> TClonesArray &truc = *tca;
> new(truc[Nstat++]) Truc(a);
> totNstat++;
> }
>
> void GenTest::Clear()
> {
> tca->Clear();
> Nstat = 0;
> }
>
> /******** Test *********/
>
> TClonesArray * Test::gtca = 0x0;
>
> Test::Test() : GenTest((unsigned int)gtca)
> {
> gtca = tca;
> }
>
> Test::~Test()
> {
> gtca = 0x0;
> }
>
> #################################
> # classLinkDef.h #
> #################################
> #ifdef __CINT__
>
> #pragma link off all globals;
> #pragma link off all classes;
> #pragma link off all functions;
> #pragma link off all typedef;
>
> #pragma link C++ class Truc;
> #pragma link C++ class GenTest;
> #pragma link C++ class Test;
>
> #endif
>
> #################################
> # test.cc (main) #
> #################################
> #include <fstream>
> #include <math.h>
>
> using namespace std;
>
> #include "TFile.h"
> #include "TTree.h"
> #include "TROOT.h"
> #include "TCanvas.h"
> #include "TApplication.h"
> #include "TGraph.h"
> #include "class.h"
>
> TROOT root("Example","Example of data reading for the Auger experiment");
> Test * pevt;
>
> int main (int argc, char *argv[])
> {
> TApplication theApp ( "App", NULL, 0 );
> gROOT->Reset( );
>
> TFile * outfile = new TFile( "/tmp/outfile.root", "RECREATE", "test" );
> TTree * resultP = new TTree( "ResultP", "EAS parameters" );
>
> pevt = new Test();
> int bufsize = 10000;
> Int_t split = 3;
> resultP->Branch( "PhysEvents", "Test", &pevt, bufsize, split );
> resultP->GetBranch("PhysEvents")->SetAddress(&pevt);
>
> for( int i=0;i<10000;i++ )
> {
> pevt->AddTruc((double)i);
> resultP->Fill();
> pevt->Clear();
> }
>
> outfile->Write();
> outfile->Print();
> outfile->Map();
> outfile->Close();
> return 0;
> }
>
> ############################
> # Makefile #
> ############################
> ROOTDIR=${ROOTSYS}/
> ROOTBIN=${ROOTDIR}bin/
> ROOTLIB=${ROOTDIR}lib/
>
> TMP=/opt/
> OBJSDIR=${TMP}Objs/
> LIBSDIR=${TMP}Libs/
> MOBJS=${OBJSDIR}classDict.o ${OBJSDIR}class.o
> CFLAGS=`${ROOTBIN}root-config --cflags` -Wall -DDPA -g
> LIBS=`${ROOTBIN}root-config --libs` -Wl,-rpath ${ROOTLIB}
> EXE=./test
>
> all: ${EXE}
>
> ${OBJSDIR}%.o: %.cc
> ${CXX} -c $< -o $@ ${CFLAGS}
>
> classDict.cc: class.h classLinkDef.h
> ${ROOTBIN}rootcint -f classDict.cc -c class.h classLinkDef.h
>
> ${LIBSDIR}libtest.so: ${MOBJS}
> g++ -shared -o $@ ${MOBJS}
>
> clean:
> rm -f ${OBJSDIR}*.o ${EXE}
> rm -f ${LIBSDIR}*.a ${LIBSDIR}*.so
> rm -f classDict.* core
>
> test: ${LIBSDIR}libtest.so ${OBJSDIR}test.o
> ${CXX} ${CFLAGS} ${OBJS} ${OBJSDIR}test.o ${LIBS} -L${LIBSDIR} -ltest -o
> $@
>
> and finally the macro:
> #############################
> # macro.cc #
> #############################
> {
> gROOT->Reset();
> gSystem->Load("/opt/Libs/libtest.so");
>
> TCanvas * c1 = new TCanvas;
> TPad * pad = new TPad("pad","",0,0,1,1) ;
>
> TChain * chainp = new TChain("ResultP");
>
> chainp->Add("/tmp/outfile.root");
> chainp->Draw("a"); // OK AT THIS POINT
>
> chainp->Add("/tmp/outfile.root");
> chainp->Draw("a"); // GIVES *** Break *** segmentation violation in root
> }
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:37 MET