Problem in drawing a TF1

Hello All,

I have a problem with the code below:

#include "TGraph.h"
#include "TMath.h"
#include "TF1.h"

Int_t cumul()
{

  //  TGraph *graph = new TGraph("../data/100Mo");

  Double_t xmin = 4.;
  Double_t xmax = 9.;

  //  TF1 * f = new TF1("f",[&](double*x, double *p){ return graph->Eval(x[0]); }, xmin, xmax, 0);
  TF1 * f = new TF1("f",[&](double *x, double *p){ return x[0]; }, xmin, xmax, 0);
  TF1 * cumulf = new TF1("cumulf",[&](double *xx, double *pp){ return f->Integral(pp[0], xx[0]); }, xmin, xmax, 1);
  cumulf->SetParameter(0, xmin);

  Double_t x = xmin;
  while(x <= xmax){
    cout << cumulf->Eval(x) << endl;
    x += .5;
  }
  //  cumulf->Draw();
  
  return 0;
}

While executing the code, the values of the function cumulf are correctly evaluated, however when I try to draw it the following exception is thrown

 *** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[<unknown binary>] (no debug info)
[<unknown binary>] (no debug info)
[<unknown binary>] (no debug info)
[/opt/root/root_v6/lib/libHist.6.12.00.so] TF1::EvalPar(double const*, double const*) /opt/root/root_v6-build/include/Math/ParamFunctor.h:0
[/opt/root/root_v6/lib/libHist.6.12.00.so] TF1::DoCreateHistogram(double, double, bool) /opt/root/root_src/hist/hist/src/TF1.cxx:2985
[/opt/root/root_v6/lib/libHist.6.12.00.so] TF1::Paint(char const*) /opt/root/root_src/hist/hist/src/TF1.cxx:0
[/opt/root/root_v6/lib/libGpad.6.12.00.so] TPad::PaintModified() /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:4066
[/opt/root/root_v6/lib/libGpad.6.12.00.so] TCanvas::Update() /opt/root/root_src/graf2d/gpad/src/TCanvas.cxx:2287
[/opt/root/root_v6/lib/libCling.so] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) /opt/root/root_src/core/metacling/src/TCling.cxx:6017
[/opt/root/root_v6/lib/libCling.so] TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) /opt/root/root_src/core/metacling/src/TCling.cxx:3069
[/opt/root/root_v6/lib/libRint.6.12.so] TRint::Run(bool) /opt/root/root_src/core/rint/src/TRint.cxx:421
[/opt/root/root_v6/bin/root.exe] main /opt/root/root_src/main/src/rmain.cxx:32
[/usr/lib/system/libdyld.dylib] start (no debug info)
[<unknown binary>] (no debug info)

I’m using root on macosx 10.12.6 compiled from source with Xcode Version 9.2 (9C40b)
Built for macosx64 From heads/v6-12-00-patches@v6-11-02-951-g31ded19fde, Dec 10 2017, 00:29:00

Thank you in advance for your help,
A.

Hi,

The crash is caused by a capture problem of the lambda. The Draw commands does basically nothing and postpone the actual paint when exiting the macro. At this point the capture of the lambda does not work anymore and therefore the TF1 is invalid.
There are two possible solution to this:

  • use Formula expressions based on string which will make the function still valid.
TF1 * cumulf = new TF1("cumulf","[&](double *xx, double *pp){ return f->Integral(pp[0], xx[0]); }", xmin, xmax, 1);

or simpler, call gPad-Update() at the end of your macro, just after Draw()

Lorenzo

Hi,

you can fix the ownership issue capturing by value:

Int_t cumul()
{
  Double_t xmin = 4.;
  Double_t xmax = 9.;

  TF1 f("f",[&](double *x, double *p){ return x[0]; }, xmin, xmax, 0);
  TF1 * cumulf = new TF1("cumulf",[=] (double *xx, double *pp) mutable { return f.Integral(pp[0], xx[0]); }, xmin, xmax, 1);
  cumulf->SetParameter(0, xmin);

  Double_t x = xmin;
  while(x <= xmax){
    cout << cumulf->Eval(x) << endl;
    x += .5;
  }
  cumulf->Draw();

  return 0;
}

I guess you should make sure that you delete cumulf; before you exit the macro, or that you also define:

TF1 *f = new TF1("f", [=](double *x, double */*p*/){ return x[0]; }, xmin, xmax, 0);

or:

TF1 *f = new TF1("f", "[&](double *x, double */*p*/){ return x[0]; }", xmin, xmax, 0);

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.