Std::bad_alloc while fitting

Hello,

i’m getting a “std::bad_alloc” while fitting a self defined function (TF1) to my data (TGraphErrors).

Since this problem could depend on my system as well:
32Bit Ubuntu 12.04 with 4GB (=> 3 GB usable) RAM
The Systemmonitor shows that ROOT uses just 29% - 39% of the usable 3GB Ram.

The core of my fit-function is a convolution of a given response-function R(z) and a function h_tilde(z, g) with g as my fit parameter.

I whish to bring the fit function in the form:
A * Integral + B * z + C
so that i have at least 4 fit parameters in total.

I narrowed the std::bad_alloc down to the number of parameter i use. It works when there are just the 2 parameters g and A and it wont work (most of the time!) when i add the other 2 parameters. (or just one)

The importend parts of my code:

Double_t MaxwFkt(Double_t *x, Double_t *par)  //h_tilde with fit-Parameter g
{
   Float_t z = x[0];
   Double_t g(par[0]);
   Double_t z0 = g * const; //const is just a scaling factor  (with µ_B, k_bT, dB/dz etc.)
   if (z>0)
      return (z0*z0*z0/(z*z*z))*TMath::Exp(-z0/z); 
   else if(z<0)
      return -(z0*z0*z0/(z*z*z))*TMath::Exp(z0/z);
   else
      return 0;
}

Double_t INTEGRA(Double_t *x, Double_t *par)  //Integral for one point z
{
   Float_t z = x[0];
   Double_t Rvalue(0), Mvalue(0), totalvalue(0), z_abwch(0);
   Double_t N(100), range(3), step(0); 

   //Responsefunction R(z):
   TF1 *f1a = new TF1("Rfit", "[0]*exp(-0.5*((x-[1])/[2])**2)+[3]*exp(-0.5*((x-[4])/[5])**2)+[6]*x+[7]", 0., 4.);
   f1a->SetParameters(28.533, 1.6966, -0.35459, 147.95, 1.6630 , 0.10936, -1.8787, 13.971);     
   //h_tilde:
   TF1 *f1b = new TF1("Maxwfkt", MaxwFkt, -5, 5, 1);  
   f1b->SetParameter(0, par[0]);   
         
   for(int i=0;i<N;i++)          //compute the integral
   {
     step = range*i/N-range/2;
     Rvalue = f1a->Eval(step+z);      
     Mvalue = f1b->Eval(step);
     totalvalue += ((Rvalue*Mvalue)/N);    
   }   
   return par[1]*totalvalue + par[2] * z + par[3];  //here is the total fit-Function
}

void macro()
{
   ...
  TCanvas *c2 = new TCanvas("c2", "Daten1");
  TF1 *f2 = new TF1("Integral", INTEGRA, 0.5,2.5, 4);   //last one is # of params
  f2->SetParameters(2, 1, 0, 0);  
  D1->Fit("Integral");               //D1 is a TGraphErrors filled with Data
  std::cout << "Chi^2/NDF: " << f2->GetChisquare()/f2->GetNDF() << std::endl << std::endl;
  D1->Draw("APE");
  f2->Draw("same");
  ...
}

(The whole Code (without parameters B and C))

Do i miss some obvious mistake that produces the std::bad_alloc or is this task just too big? (i dont expect the second one to be true)
Do you have some ideas that could help me with this issue?

Thanks for reading.
Martin

In your INTEGRA" function, just before the “return” statement, add:
delete f1a; delete f1b;

Thats great! This is what i meant with “obvious mistake”. It seems to work now.

Thank you for your help!

Greetings,
Martin

The “obvious” mistake is really that you use pointers without reason. Instead use normal objects (TF1 f1a(“Rfit”, “[0]exp(-0.5((x-[1])/[2])**2)+[3]exp(-0.5((x-[4])/[5])**2)+[6]*x+[7]”, 0., 4.)) which will give you much less headaches. The memory they use will automatically be released at the end of the block in which they were created. Pointers are a much rarer use case than the ROOT examples make you believe.

Cheers,

Benjamin

You are right - I never gave it a thought and wrote my macros with trial and error and similar examples. Thanks for pointing that out! (I always thought they have to be pointers to be honest :smiley:)

But i never had a situation before, where i use a TF1 (or a *TF1) many times in a loop.