Hi rooters, I waited a long time before posting this, but I have no clue on this problem so... I seem to have a memory leak that i cannot trace to my personal code...I have made a much simplified version of code which apparently reproduces the problem. The leak is eating something like 10 Kbytes of memory for each "iteration" in the main loop of this code, it's bigger in the full code version. This prevents me from running on big amounts of data (which is needed, of course). The problem happens when reading a ROOT TTree file which contains occurences of one simple structure with one TObjArray* member, the TObjArray elements themselves containing another object which itself has a TClonesArray* member. So, this is a story about storing and reading in a Root TTree a TObjArray which elements are mainly TClonesArray. The problem appears while READING the TTree. Another problem is that, after a few thousand events, the program is printing out thousands of Warning messages like: Warning in <TObjectTable::Remove>: 0x0a61b7b4 not found at 1739 Warning in <TObjectTable::Remove>: 0x0a61d8fc not found at 1739 Warning in <TObjectTable::Remove>: 0x0a61d8f0 not found at 1739 ... Warning in <TObjectTable::Remove>: 0x0a7a3a5c not found at 5779 Warning in <TObjectTable::Remove>: 0x0a7a3a50 not found at 5779 Warning in <TObjectTable::Remove>: 0x0a7a3a98 not found at 5779 Warning in <TObjectTable::Remove>: 0x0a7a3a18 not found at 5779 I have no idea of what is happening, so i am calling the experts... Configuration info: Linux RedHat 6.2, Root 3.01/06, the program is compiled whith gcc egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) I'll try to give here the main elements of the code, so people can see if something is wrong somewhere. Thanks any help/suggestion // //------Base class stored in tree-------------------------- // class TauEvent : public TObject { public: //Constructor TauEvent(); //Destructor ~TauEvent(); //Accessors TauC1 &GetC1(Int_t iC1); //returns a pointer to a 3-1 comb. array public: TObjArray *C1; //The TObjArray public: ClassDef(TauEvent,1) }; // //-----Class to be stored in the TObjArray-------------------- // class TauC1 : public TObject { public: //Constructor TauC1(); //Destructor ~TauC1(); //Access sub data TauC2 *AddC2(Int_t iC2); TauC2 &GetC2(Int_t iC2); TClonesArray &GetC2() { return *C2;}; //3-body info TLorentzVector V1; private: TClonesArray *C2; //the TClonesArray public: ClassDef(TauC1,1) }; // //--------Constructor and destructor of TauEvent // //contructor ClassImp(TauEvent) TauEvent::TauEvent() : C1(0) { C1=new TObjArray(); } //destructor TauEvent::~TauEvent() { if (C1) { if(C1->GetEntries()>0) C1->Delete(); delete C1; } } // //--------Constructor and destructor of TauC1 // //contructor ClassImp(TauC1) TauC1::TauC1() { C2=new TClonesArray("TauC2"); } //destructor TauC1::~TauC1() { if(C2) { if(C2->GetEntries()>0) C2->Delete(); delete C2; } } // //------Data fill & access routines // TauC2 *TauC1::AddC2(Int_t iC2) { return (new ((*C2)[iC2]) TauC2); } // //TTree creation code // Rfile=new TFile("Event.root","RECREATE","EventInfo",1); //0=no compress Rtree=new TTree("EventTree","EventInfo tree",0); Rtree->SetBranchStyle(0); //!!!!old style branch (ROOT 3.01/06) Rtree->Branch("C1", "TObjArray", &(EventInfo.C1), 2048, 0); // //Writing loop code (called for each "event") // for (int itau1=0;itau1<1;itau1++) { //structure 1 loop TauC1 *C1=new TauC1; C1->V1.SetXYZT(1,2,3,4); for (int itau2=0;itau2<1;itau2++) { //structure 2 loop TauC2 *C2=C1->AddC2(itau2); C2->V2.SetXYZT(10,20,30,40); } EventInfo.C1->Add(C1); //Fill C1 structure level } Rtree->Fill(); //final fill for root data EventInfo.C1->Delete(); //clear local objects in event Tree // // Reading loop code // TChain *Tree; //create global tree TBranch *C1Branch; TauEvent EvI; Int_t NEventMax; TObjectTable* gObjectTable; //Load tree Int_t init_tree() { //Multi file access Tree=new TChain("EventTree"); Tree->Add("Event.root/EventTree"); //Connect root file //Connect root branches to local variables ("EvI") C1Branch=Tree->GetBranch("C1"); C1Branch->SetAddress(&(EvI.C1)); C1Branch->SetAutoDelete(kTRUE); // Int_t Nevent=(Int_t)Tree->GetEntries(); cout << "Main: Number of events in tree: " << Nevent << endl; return 0; } //reading loop Int_t plot_t31() { TH1F hV1X("hV1X", "V1 x", 60, 0., 5.); Int_t Nevent=(Int_t)Tree->GetEntries(); for(int iev=0;iev<TMath::Min(Nevent,NEventMax);iev++) { //fill histos Tree->GetEntry(iev); if(iev%100==0) cout << "iev: " << iev << endl; // gObjectTable->Print(); for(int iC1=0;iC1<EvI.C1->GetEntries();iC1++) { TauC1 &C1=EvI.GetC1(iC1); Double_t V1X=C1.V1.X(); hV1X.Fill(V1X); cout << "V1X:" << V1X << endl; } if(EvI.C1->GetEntries()>0) EvI.C1->Delete(); //clear local objects in event } TCanvas *c1 = new TCanvas("c1","Test",200,10,900,1000); c1->Clear(); c1->Divide(1,2); c1->cd(1); hV1X.DrawCopy(); return 0; }
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:02 MET