[ROOT] Reading and cleaning of TClonesArray

From: Ruben Shahoyan (Ruben.Shahoyan@cern.ch)
Date: Mon Nov 25 2002 - 22:02:58 MET


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