Memory leak in TFile->Get()

The following code produces a memory leak. The code basically runs over a list of events, and uses values from the events to chose histograms saved in TFile, in one of several TCanvases which each contains several TPads. These histograms contain information used to calculate a value for the event, etc. The memory leak come from the TCanvas/TPad/TH1F that come from the TFile. I have set up the code every way I could think of, but as long as I set the TCanvas to the one in the TFile I et the leak. I have tried to delete the canvas, but it doesnt help. Is there any way around this?

Using root 5.18.00a

Thanks

Dan

[code]
TH1F *product = new TH1F(“product”,“product”,emf_bin,emf_min,emf_max);
TCanvas *canvas0;
TPad *pad0;
TH1F *emfrac_var_val_eng;

Int_t test_nentries = (Int_t)testTree->GetEntries();
for (Int_t q = 0;q < test_nentries;q++){

    testTree->GetEntry(q);     
    
    bool w_first = true;
    
    for(int w = 0; w<num_vars; w++){
    
        TFile file0(train_file_in,"read");
        canvas0 = (TCanvas*)file0.Get(Form("%s_%d",vars[w],test_energy_hist));
        pad0 = (TPad*)canvas0->GetPrimitive(Form("%s_%d_%d",vars[w],test_energy_hist,bin_var[w]+1));
        emfrac_var_val_eng = (TH1F*)pad0->GetPrimitive(Form("emfrac_%d_%d",w,test_energy_hist));
        
        if (w_first==true){
          product->Add(emfrac_var_val_eng);
          w_first = false;
        }else{
          product->Multiply(emfrac_var_val_eng);
        }

// delete emfrac_var_val_eng;
// delete pad0;
// delete canvas0;
emfrac_var_val_eng->Delete();
pad0->Delete();
canvas0->Delete();
}else{
m_var[w] = 0;
s_var[w] = 100;
}
if(!w_first) pid_product = product->GetMaximumBin()*(emf_max-emf_min)/emf_bin;
else pid_product = 0;

      outTree->Fill();

      if(q%500 == 0) cout<<"On Entry "<<q<<endl;
  }      

}[/code][/code]

I suggest to check first if the following loop still shows a leak or not:

for (Int_t q = 0;q < test_nentries;q++){ testTree->GetEntry(q); }

then if this loop has a leak:

for (Int_t q = 0;q < test_nentries;q++){ testTree->GetEntry(q); outTree->Fill(); }
Rene

The memory leak does not occur in either of the situations. I tried commenting out every section of code, and the memory leak only occurs when I have the

[code]TFile file0(train_file_in,“read”);
canvas0 = (TCanvas*)file0.Get(Form("%s_%d",vars[w],test_energy_hist));
pad0 = (TPad*)canvas0->GetPrimitive(Form("%s_%d_%d",vars[w],test_energy_hist,bin_var[w]+1));
emfrac_var_val_eng = (TH1F*)pad0->GetPrimitive(Form(“emfrac_%d_%d”,w,test_energy_hist));

        if (w_first==true){
          product->Add(emfrac_var_val_eng);
          w_first = false;
        }else{
          product->Multiply(emfrac_var_val_eng);
        }

// delete emfrac_var_val_eng;
// delete pad0;
// delete canvas0;
emfrac_var_val_eng->Delete();
pad0->Delete();
canvas0->Delete(); [/code]

code in place, and only stops when I comment it out up to the declaration of the TCanvas. (There is actually quite a bit more code in the loop, but non of it is directly related to the above, and worked fine before I added this code, and when I remove it.)

Hi,

Please let me know if there is any more information I can give you to help reproduce/solve this problem.

Are there other methods for getting the histogram out of TCanvas other than whats used here?

Thanks for your help

Dan

Could you post a data file and the shortest possible running script reproducing your problem?

Rene

I have pared down the code to the bare minimum and I still get the leak … please let me know if you need anything else.

The data file was too large to post, so I have dropped the files here:

minos.phy.tufts.edu/danche/ROOT_ … EST_FILES/

Thanks

Dan

I have fixed the leak in your inner loop below (see comments)

Rene

  //for pid_product
  TH1F *product = new TH1F("product","product",emf_bin,emf_min,emf_max); 
  TCanvas *canvas0=0;
  TPad *pad0=0;
  TH1F *emfrac_var_val_eng=0;
  TFile file0(train_file_in,"read");  
  
  for (Int_t q = 0;q < 1000000;q++){
        bool w_first = true;
        
        cout<<"start evaluatePID ..."<<endl;
        for(int w = 0; w<num_vars; w++){
          test_val[w] = 0.5;
          test_Energy_GeV = 2.0;
          test_energy_hist = (int) test_Energy_GeV;

          if(test_val[w]>-999&&test_val[w]!=-10.0&&test_energy_hist>=0&&test_energy_hist<10){   
            bin_var[w] = (int) (test_val[w]*var_bin/(var_maxs[w]-var_mins[w])-(var_mins[w]*var_bin/(var_maxs[w]-var_mins[w])));
            
            //for product pid
            canvas0 = (TCanvas*)file0.Get(Form("%s_%d",vars[w],test_energy_hist)); 
            pad0 = (TPad*)canvas0->GetPrimitive(Form("%s_%d_%d",vars[w],test_energy_hist,bin_var[w]+1)); 
            emfrac_var_val_eng = (TH1F*)pad0->GetPrimitive(Form("emfrac_%d_%d",w,test_energy_hist));
              
            if (w_first==true){
              product->Add(emfrac_var_val_eng);
              w_first = false;
            }else{
              product->Multiply(emfrac_var_val_eng);
            }
            
            //a pad is not owner of the objects inside. In case a pad/canvas
            //contains subpads, one must explicitly delete all objects
            //in the subpads.
            TIter next(canvas0->GetListOfPrimitives());
             TObject *obj;
             while ((obj=next())) {
                if (obj->InheritsFrom("TPad")) {
                   TPad *pad =(TPad*)obj;
                   pad->GetListOfPrimitives()->Delete();
                }
             }
                
             delete canvas0;
          }

      }

      if(!w_first) pid_product = product->GetMaximumBin()*(emf_max-emf_min)/emf_bin;
      else pid_product = 0;
      cout<<"PID_Product = "<<pid_product<<endl;
 
      outTree->Fill();

      if(q%500 == 0) cout<<"On Entry "<<q<<endl;
   
  }

Rene,

Does the trick, thanks a bunch

Dan