Re: [ROOT] Reading and cleaning of TClonesArray

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Nov 26 2002 - 00:36:28 MET


Hi Ruben,

When your TClonesArray contains dynamic structures (like TNamed),
you must delete these dynamic structures before clearing
the array at each entry. I give an example of what you can do
below, still preserving some of the advantages of a TClonesArray.

Rene Brun

//_________________________________________________________
void trrd()
{
  printf("Reading back the tree\n");
  char name[100];
  TClonesArray* fVTVerts = new TClonesArray("TNamed",10);
  //
  TFile* flin = new TFile("trout.root");
  TTree *tree = (TTree*)flin->Get("tree");
  TBranch* trbr = tree->GetBranch("mybr");
  trbr->SetAddress(&fVTVerts);
  //
  int nev = tree->GetEntries();
  int iv,nv;
  for (int iev=0;iev<nev;iev++) {
    trbr->GetEntry(iev);
    nv = fVTVerts->GetEntriesFast();
    printf("\n\nRead Event %d %d Old Vertices Are\n",iev,nv);
    fVTVerts->Print();
    printf("\nNow will call TClonesArray::Delete() and Create new
Vertices\n");
    for (iv=0;iv<nv;iv++)
((TNamed*)fVTVerts->At(iv))->SetNameTitle("","");
    fVTVerts->Clear();
    // Reanalyze event, creating new vertices
    nv = gRandom->Integer(5)+1;
    for (iv=0;iv<nv;iv++) {
      sprintf(name,"New Vtx %d of Ev %d",iv,iev);
      TNamed* vp = new ((*fVTVerts)[iv]) TNamed(name,name);
    }
    printf("\nUpdated Event: New Vertices Are:\n");
    fVTVerts->Print();
    for (iv=0;iv<nv;iv++)
((TNamed*)fVTVerts->At(iv))->SetNameTitle("","");
    fVTVerts->Clear();
  }
  delete flin;
  delete fVTVerts;
}


On Mon, 25 Nov 2002, Ruben Shahoyan wrote:

> Hello,
> I have encontered the following problem:
> I am reading from the tree an event, which among other branches has one
> with TClonesArray of the vertices (objects which allocate the memory).
> I need to reanalize the event, so I have to clean the loaded vertices and
> create new ones. But if I call TClonesArray::Delete() to clean this array,
> loading next event produces SegVol.
> 
> Below I show the simple macros demonstrating the problem. Does anybody 
> know the solution?
> 
> Thanks in advance,
> 	Ruben Shahoyan
> 
> 
> //_____________________ Sample Macro________________________
> void trwr(int nev);
> void trrd();
> 
> void trtest(int nev=20) 
> {
>   // Step 1: Create tree, with the branch of TClonesArray of the objects
>   // allocating memory
>   trwr(nev);
>   //
>   // Step 2: Read the tree, trying to "modify" the TClonesArray
>   trrd();
> }
> 
> //_________________________________________________________
> void trwr(int nev)
> {
>   printf("Generating the tree with %d events\n",nev);
>   char name[100];
>   Int_t bfsize=32000;
>   Int_t split=2;
>   TClonesArray* fVTVerts = new TClonesArray("TNamed",10);
>   fVTVerts->SetOwner();
>   //
>   TFile* flout = new TFile("trout.root","RECREATE");
>   TTree *tree = new TTree("tree","tree");
>   tree->Branch("mybr","TClonesArray",&fVTVerts,bfsize,split);
>   //
>   for (int iev=0;iev<nev;iev++) {
>     fVTVerts->Delete();
>     int nv = gRandom->Integer(10)+1;
>     for (int iv=0;iv<nv;iv++) {
>       sprintf(name,"Vtx %d of Ev %d",iv,iev);
>       TNamed* vp = new ((*fVTVerts)[iv]) TNamed(name,name);
>     }
>     tree->Fill();
>   }
>   tree->Write();
>   delete tree;
>   flout->Close();
>   delete flout;
>   delete fVTVerts;
> }
> 
> //_________________________________________________________
> void trrd()
> {
>   printf("Reading back the tree\n");
>   char name[100];
>   TClonesArray* fVTVerts = new TClonesArray("TNamed",10);
>   fVTVerts->SetOwner();
>   //
>   TFile* flin = new TFile("trout.root");
>   TTree *tree = (TTree*)flin->Get("tree");
>   TBranch* trbr = tree->GetBranch("mybr");
>   trbr->SetAddress(&fVTVerts);
>   //
>   int nev = tree->GetEntries();
>   for (int iev=0;iev<nev;iev++) {
>     trbr->GetEntry(iev);
>     printf("\n\nRead Event %d %d\n Old Vertices Are",iev,fVTVerts->GetLast()+1);
>     fVTVerts->Print();
>     printf("\nNow will call TClonesArray::Delete() and Create new Vertices\n");
>     //fVTVerts->Clear();  !! Works with Clear, but will lead to memory leak! 
>     fVTVerts->Delete();
>     // Reanalyze event, creating new vertices
>     int nv = gRandom->Integer(5)+1;
>     for (int iv=0;iv<nv;iv++) {
>       sprintf(name,"New Vtx %d of Ev %d",iv,iev);
>       TNamed* vp = new ((*fVTVerts)[iv]) TNamed(name,name);
>     }
>     printf("\nUpdated Event: New Vertices Are:\n");
>     fVTVerts->Print();
>     //
>   }
>   delete tree;
>   flin->Close();
>   delete flin;
>   delete fVTVerts;
> }
> 
> 



This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:20 MET