Memory leak

Hi Rooters,
I would ask for your advice on a memory leak problem (presumible).
I want to make a fit with mc templates , and I’m using TFractionFitter, however, memory allocation keeps growing after each iteration. It does not seem that the delete method is working, so I wonder if TFractionFitter keeps something in memory i should delete, or I’m missing something. Any help would be appreciated.

The code is the following :

int Fit_data(int fit_r0,int fit_r1, TH1F *data, TH1F *mc0,TH1F *mc1, TH1F* &result, double &frac0,double &frac1, double &fracerr0,double &fracerr1, double &chi2ndof)
{

 TObjArray *mc = new TObjArray(2);
 mc->Add(mc0);
 mc->Add(mc1);
 TFractionFitter* fit = new TFractionFitter(data, mc); // initialise

 fit->Constrain(0,0,1.);
 fit->Constrain(1,0,1.);

 fit->SetRangeX(fit_r0,fit_r1);
 Int_t status = fit->Fit();

 if (status == 0) {
 fit->GetResult(0,frac0,fracerr0);
 fit->GetResult(1,frac1,fracerr1);
 }

 double chi2=0;
 int    ndf =1;

 if (status == 0) {
  result = (TH1F*)fit->GetPlot();
  chi2=fit->GetChisquare();
  ndf =fit->GetNDF();
  chi2ndof=chi2/double(ndf);
 }

//clean up
delete  fit;
delete  mc ;

if(status!=0){return 0;}
return 1;
}

void analysis()
{
//initialize
TFile *file_data;
file_data=new TFile("inputfile.root","READ");
const Int_t Types=38;
const Int_t TrPatt=7;

const int nbin=16;
double xlow[nbin+1]={
 0., 1., 2., 2. , 3.  , 4.,
 5. , 6. , 7. , 9. , 11. , 15.,
 20., 28., 42., 65., 100. };

int init =4;
const Int_t nbinrange=12;   

//....Def Histos....//
TH3F *BDTTRDL_E[Types][TrPatt][2];


string hName,hTitle;
for(int type=0;type<Types;type++){
for(int pat=0; pat<TrPatt;pat++){
for(int tag=0; tag<2; tag++){
hName=Form("hBDTree_TRDL_E_Type%d_%d_%d",type,pat,tag);
BDTTRDL_E[type][pat][tag] =(TH3F*)file_data->Get(hName.c_str());
BDTTRDL_E[type][pat][tag]->SetName(Form("BDTTRDL_E_%d_%d_%d",type,pat,tag)); 
BDTTRDL_E[type][pat][tag]->SetTitle(hTitle.c_str());
}
}
}

for(int type=0;type<Types;type++){
for(int pat=0; pat< TrPatt;pat++){
for(int j=init;j<nbinrange+init;j++){
for(int tag=0;tag<2;tag++){

int data_temp,temp_data;
if(tag==0){
data_temp=1;
temp_data=0;
}
else{
data_temp=0;
temp_data=1;
}

BDTTRDL_E[type][pat][data_temp]  ->GetZaxis()->SetRange(j+1,j+1); // data
BDTTRDL_E[0][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates
BDTTRDL_E[1][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates
BDTTRDL_E[0][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates
BDTTRDL_E[1][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates

BDTTRDL_R[type][pat][data_temp]  ->GetZaxis()->SetRange(j+1,j+1); // data
BDTTRDL_R[0][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates
BDTTRDL_R[1][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates
BDTTRDL_R[0][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates
BDTTRDL_R[1][pat][temp_data]  ->GetZaxis()->SetRange(j+1,j+1); // templates


TH2F *BDTTRD_E=(TH2F*) BDTTRDL_E[type][pat][data_temp]->Project3D("yx");
BDTTRD_E->SetName(Form("BDTTRD_E_%d_%d_%d_%d",type,pat,j,tag));
BDTTRD_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1]));
//templates
TH2F *BDTTRD_temp_neg_E=(TH2F*) BDTTRDL_E[keBDTe][pat][temp_data]->Project3D("yx");
BDTTRD_temp_neg_E->SetName(Form("BDTTRD_temp_neg_E_%d_%d_%d_%d",type,pat,j,tag));
BDTTRD_temp_neg_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1]));

TH2F *BDTTRD_temp_pos_E=(TH2F*) BDTTRDL_E[kpBDTp][pat][temp_data]->Project3D("yx");
BDTTRD_temp_pos_E->SetName(Form("BDTTRD_temp_pos_E_%d_%d_%d_%d",type,pat,j,tag));
BDTTRD_temp_pos_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1]));


TH2F *BDTTRD_temp_neg_bdt_E=(TH2F*) BDTTRDL_E[keTRDe][pat][temp_data]->Project3D("yx");
BDTTRD_temp_neg_bdt_E->SetName(Form("BDTTRD_temp_neg_bdt_E_%d_%d_%d_%d",type,pat,j,tag));
BDTTRD_temp_neg_bdt_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1]));  

TH2F *BDTTRD_temp_pos_bdt_E=(TH2F*) BDTTRDL_E[kpTRDp][pat][temp_data]->Project3D("yx");
BDTTRD_temp_pos_bdt_E->SetName(Form("BDTTRD_temp_pos_bdt_E_%d_%d_%d_%d",type,pat,j,tag));
BDTTRD_temp_pos_bdt_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1])); 

//rebin
BDTTRD_E                       ->Sumw2();     
BDTTRD_temp_neg_E       ->Sumw2();   
BDTTRD_temp_pos_E       ->Sumw2();  
BDTTRD_temp_neg_bdt_E ->Sumw2();  
BDTTRD_temp_pos_bdt_E ->Sumw2(); 
BDTTRD_E                        ->Rebin2D(4,2); 
BDTTRD_temp_neg_E        ->Rebin2D(4,2);
BDTTRD_temp_pos_E        ->Rebin2D(4,2);
BDTTRD_temp_neg_bdt_E ->Rebin2D(4,2);
BDTTRD_temp_pos_bdt_E ->Rebin2D(4,2);

int nbins_trd=BDTTRD_E->GetNbinsX();
int nbins_bdt=BDTTRD_E->GetNbinsY();

TH1F *temp_trd_neg =  (TH1F*)BDTTRD_temp_neg_E    ->ProjectionX(Form("temp_trd_neg_%d_%d_%d_%d",type,pat,j,tag),-1,-1,"");
TH1F *temp_trd_pos =  (TH1F*)BDTTRD_temp_pos_E    ->ProjectionX(Form("temp_trd_pos_%d_%d_%d_%d",type,pat,j,tag),-1,-1,"");
TH1F *temp_bdt_neg =  (TH1F*)BDTTRD_temp_neg_bdt_E->ProjectionY(Form("temp_bdt_neg_%d_%d_%d_%d",type,pat,j,tag),-1,-1,"");
TH1F *temp_bdt_pos =  (TH1F*)BDTTRD_temp_pos_bdt_E->ProjectionY(Form("temp_bdt_pos_%d_%d_%d_%d",type,pat,j,tag),-1,-1,"");


for(int nlk=0;nlk<nbins_trd-1;nlk++){
for(int nbd=0;nbd<nbins_bdt-1;nbd++){

int ibin_trd = nlk+1;
int ibin_bdt = nbd+1;

///////... Take Data in range ...//////

TH1F *TRD_E= (TH1F*)BDTTRD_E->ProjectionX(Form("TRD_E_%d_%d_%d_%d_d_%d",type,pat,j,tag,nlk,nbd),ibin_bdt,-1,""); 
TRD_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1]));

TH1F *BDT_E= (TH1F*)BDTTRD_E->ProjectionY(Form("BDT_E_%d_%d_%d_%d_d_%d",type,pat,j,tag,nlk,nbd),-1,ibin_trd,""); 

BDT_E->SetTitle(Form("E in %.2f-%.2f GeV",xlow[j], xlow[j+1]));

//fit normalizations 
 TH1F *data=(TH1F*)TRD_E          ->Clone(Form("data_%d_%d_%d_%d_d_%d",type,pat,j,tag,nlk,nbd));        
 TH1F *mc0 =(TH1F*)temp_trd_neg->Clone(Form("mc0_%d_%d_d_%d_d_%d",type,pat,j,tag,nlk,nbd));            
 TH1F *mc1 =(TH1F*)temp_trd_pos->Clone(Form("mc1_%d_%d_%d_%d_%d_%d",type,pat,j,tag,nlk,nbd));
 TH1F *result=new TH1F();

 double frac[2]    ={0};
 double fracerr[2]={0};
 double chifit=0;
 int range_fit_trd_0 ;
 int range_fit_trd_1 ;

 range_fit_trd_0 = 1;
 range_fit_trd_1 = ibin_trd;  
 if(data->Integral(range_fit_trd_0,range_fit_trd_1)<100) continue;

//perform fit
int status=Fit_data(range_fit_trd_0,range_fit_trd_1,data,mc0,mc1,result,frac[0],frac[1],fracerr[0],fracerr[1],chifit) ;

//cleanning
delete  BDT_E;
delete  TRD_E;
if(data)   {delete  data  ;}
if(mc0)    {delete  mc0   ;}
if(mc1)    {delete  mc1   ;}
if(result) {delete  result;}
}//end bdtloop
}//end trdloop

delete  BDTTRD_E              ;  
delete  BDTTRD_temp_neg_E     ;
delete  BDTTRD_temp_pos_E     ;
delete  BDTTRD_temp_neg_bdt_E ;
delete  BDTTRD_temp_pos_bdt_E ;
delete  temp_trd_neg          ;  
delete  temp_trd_pos          ;
delete  temp_bdt_neg          ; 
delete  temp_bdt_pos          ;    

}//end tag
}//eof j
}//end of tr pat 
}//end types

}

Thank you!

Try:
valgrind --tool=memcheck --leak-check=full [–show-reachable=yes] [–num-callers=50] [–track-origins=yes] [–db-attach=yes] --suppressions=root-config --etcdir/valgrind-root.supp root-config --bindir/root.exe -l -q 'YourMacro.cxx[++][(Any, Parameters, You, Need)]'
or:
valgrind --tool=memcheck --leak-check=full [–show-reachable=yes] [–num-callers=50] [–track-origins=yes] [–db-attach=yes] --suppressions=root-config --etcdir/valgrind-root.supp YourExecutable [Any Options You Need]
and especially carefully study messages that appear in the beginning of the output.
(Note: the “–show-reachable=yes” option will give you too many warnings, I believe.)

Dear Wile,
Thank you for your response. I have tried with valgrind and the output is quite cryptic…
This is the summary (after a bunch of stdout)
==32290== LEAK SUMMARY:
==32290== definitely lost: 370,604 bytes in 436 blocks
==32290== indirectly lost: 30,419 bytes in 725 blocks
==32290== possibly lost: 5,983,741 bytes in 119,664 blocks
==32290== still reachable: 597,501,790 bytes in 379,683 blocks
==32290== suppressed: 14,156,106 bytes in 275,533 blocks

Try to run it with “–leak-check=full” (and without “–show-reachable=yes” -> this option would give you too many warnings) and carefully study messages that appear in the beginning of the output. :wink: