Deleting TH1Fs, TPads, TCanvases

Hi,

I’m looping over a number of events, and I want my code to create histograms, canvases and pads as it goes. I would like to release memory at the beginning of the next event (so that the last event leaves pads & histograms that it has created in memory). I think I know how to do everything, except for taking care of the TPad memory leak. Reading Chapter 8 of the manual (Object ownership) did not help me.

Here’s a small macro that reproduces what I want to do (that has a memory leak because TPads are never deleted)

Thanks.

–Christos

#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TH1F.h>
#include <TLeaf.h>
#include <TBranch.h>
#include <TCanvas.h>
#include <TObjArray.h>
#include <TRandom.h>
#include <TPostScript.h>

using namespace std;

int run(void)
{

TCanvas * canv = 0;
TPad * p1 = 0;
TPad * p2 = 0;
TPostScript * ps = 0;

for (Int_t jentry = 0; jentry != 10; ++jentry)
{ // event loop

  // release memory (previous event)
  if(canv) delete canv;
  if(ps) delete ps;
  
  gDirectory->Delete("h10");
  gDirectory->Delete("h20");
  gDirectory->Delete("h30");
  gDirectory->Delete("h40");

  // create new histograms
  TH1F * h10 = new TH1F("h10","hist 10", 100, -5, 5);
  TH1F * h20 = new TH1F("h20","hist 20", 100, -10, 10);
  TH1F * h30 = new TH1F("h30","hist 30", 100, -15, 15);
  TH1F * h40 = new TH1F("h40","hist 40", 100, -20, 20);

  // fill histograms
  for(Int_t i = 0; i != 100; ++i)
{
  h10->Fill(gRandom->Gaus(0,1));
  h20->Fill(gRandom->Gaus(0,2));
  h30->Fill(gRandom->Gaus(0,3));
  h40->Fill(gRandom->Gaus(0,4));
}

  ps = new TPostScript("output.ps",111);
  // plot histograms
  canv = new TCanvas("canv", "my canvas", 1,0,630,788);

  ps->NewPage();
  canv->Clear();
  p1 = new TPad("p1","p1",0.05,0.50,0.95,0.95) ;
  p1->Draw();
  p2 = new TPad("p2","p2",0.05,0.03,0.95,0.48 ) ;
  p2->Draw();    

  p1->cd(); h10->Draw();
  p2->cd(); h20->Draw();
  canv->Update();

  ps->NewPage();
  canv->Clear();
  p1 = new TPad("p1","p1",0.05,0.50,0.95,0.95) ;
  p1->Draw();
  p2 = new TPad("p2","p2",0.05,0.03,0.95,0.48 ) ;
  p2->Draw();    

  p1->cd(); h30->Draw();
  p2->cd(); h40->Draw();
  canv->Update();

  ps->Close();
} // event loop

return 0;
}

When you delete a canvas, all its pad are automatically deleted. You should not see a memory leak.
Note that your example can be simplified as follows:

Rene

               int run(void) 
               { 

               TCanvas * canv = 0; 
               TPad * p1 = 0; 
               TPad * p2 = 0; 

               for (Int_t jentry = 0; jentry != 10; ++jentry) 
               { // event loop 

               // release memory (previous event) 
               if(canv) delete canv; 

               gDirectory->Delete("h10"); 
               gDirectory->Delete("h20"); 
               gDirectory->Delete("h30"); 
               gDirectory->Delete("h40"); 

               // create new histograms 
               TH1F * h10 = new TH1F("h10","hist 10", 100, -5, 5); 
               TH1F * h20 = new TH1F("h20","hist 20", 100, -10, 10); 
               TH1F * h30 = new TH1F("h30","hist 30", 100, -15, 15); 
               TH1F * h40 = new TH1F("h40","hist 40", 100, -20, 20); 

               // fill histograms 
               for(Int_t i = 0; i != 100; ++i) 
               { 
               h10->Fill(gRandom->Gaus(0,1)); 
               h20->Fill(gRandom->Gaus(0,2)); 
               h30->Fill(gRandom->Gaus(0,3)); 
               h40->Fill(gRandom->Gaus(0,4)); 
               } 

               // plot histograms 
               canv = new TCanvas("canv", "my canvas", 1,0,630,788); 

               p1 = new TPad("p1","p1",0.05,0.50,0.95,0.95) ; 
               p1->Draw();
               p2 = new TPad("p2","p2",0.05,0.03,0.95,0.48 ) ; 
               p2->Draw();
               p1->cd(); h10->Draw();
               p2->cd(); h20->Draw();
               canv->Update();
               if (jentry == 0) canv->Print("output.ps("); 
               else             canv->Print("output.ps"); 

               canv->Clear(); 
               p1 = new TPad("p1","p1",0.05,0.50,0.95,0.95) ; 
               p1->Draw();
               p2 = new TPad("p2","p2",0.05,0.03,0.95,0.48 ) ; 
               p2->Draw();
               p1->cd(); h30->Draw();
               p2->cd(); h40->Draw();
               canv->Update(); 
               if (jentry == 9) canv->Print("output.ps)"); 
               else             canv->Print("output.ps"); 

               } // event loop 


               return 0; 
               }

Hi Rene,

[quote=“brun”]When you delete a canvas, all its pad are automatically deleted. You should not see a memory leak.
[/quote]

Yes, you are right, there is no memory leak (I expected to have one, but I never checked it for a large # of events).

Thanks.

–Christos