Calling TH1F function in a loop, segmentation violoation

Hi,
My question may not be Root related but I am not sure. I am faced with segmentation violation problems.
My goals are the following:

  1. load a 2d histogram from a set of files
  2. from the 2d histogram, extract 1d histograms in a for-loop
  3. i use each 1d histogram to fit and retrieve a fit parameter (inside the for loop) then store in an array.
    i start to fail in 2) and 3).
TH1F *readDataFile(char* fname, int nch) {
  int ch,counts;
  float fc;
  TH1F *h = new TH1F("h1","",nch,-0.5,nch-0.5);
  h->Sumw2();
  FILE* fp=fopen(fname,"r");
  if (fp==NULL) {
    printf("Could not open file %s\n",fname);
    return h;
  }
  for (int j=0; j<nch; j++) {  
      fscanf(fp,"%d %f",&ch,&fc);
      counts=fc;    
      h->SetBinContent(j+1,fc);
  }
  fclose(fp); 
  return h;
}

TH2F* createScan(char* fn, int mi, int ma, int step, int nch) {    
  char fname[1000];
  TH1F *hdum;
  TH2F *h2 = new TH2F("h2","",nch,-0.5,nch-0.5,((ma-mi)/step)+1,mi-(Double_t)step/2.,ma+(Double_t)step/2.);
  h2->SetStats(kFALSE);  
  for (int i=mi; i<ma+1; i=i+step) {
    sprintf(fname,fn,i); 
    hdum=readDataFile(fname, nch);
    for (int j=0; j<nch; j++)
      h2->Fill(j,i,hdum->GetBinContent(j+1));
    delete hdum;   
  }
  return h2; 
}

TH1F * getCh(TH2F* h2, int chan) {
  int nstep=h2->GetYaxis()->GetNbins();
  Double_t mi=h2->GetYaxis()->GetXmin();
  Double_t ma=h2->GetYaxis()->GetXmax();  
  char channel[]= "Channel";
  char chanNum[100]; 
  sprintf(chanNum, "%s %d", channel, chan);  
  TH1F *h1=new TH1F("h1",chanNum,nstep,mi,ma);
  for (int i=1; i<nstep+1; i++) { 
    h1->SetBinContent(i, h2->GetBinContent(chan+1,i));    
  }
  return h1;
}


Double_t FitERF4(TH1F *h1, float min,Double_t *mypar, Double_t *emypar, int plot) {
	float chi=100.;
	float flex;	
	float maxx = h1->GetMean()-15;
	mypar[3]=h1->GetBinContent(h1->GetXaxis()->FindBin(maxx-15));
		
	TF1* fitfunc;
	TF1 *func = new TF1("func",erfFunction3,min,maxx,5);
	
	func->SetParameters(mypar);
	func->SetParameter(0,0.);
	func->SetParLimits(0,0., 10.);	
	func->SetParameter(1,390.);
	func->SetParLimits(1,360, 430);	
	func->SetParameter(2,10.);
	func->SetParLimits(2,0.,100.);		
	func->SetParameter(4,0.1);
	func->SetParLimits(4,0., 1.);		
	func->SetRange(min,maxx);
	  
  	if (plot) {
  		h1->Fit("func","R"); 
  	}else{
  		h1->Fit("func","R0QV");
  	}  
  	fitfunc = h1->GetFunction("func");
	fitfunc->GetParameters(mypar);                               
  	emypar[1]=fitfunc->GetParError(1);                           
  	emypar[0]=fitfunc->GetParError(0);
  	emypar[2]=fitfunc->GetParError(2);
  	emypar[3]=fitfunc->GetParError(3);
  	emypar[4]=fitfunc->GetParError(4);
  	chi = fitfunc->GetChisquare()/(fitfunc->GetNDF());
  	flex = fitfunc->GetParameter(1);   	
  	delete func;
	if (plot)
           printf("Chi square =%e\n",chi);   
	return flex;
}

float *flexpoint(TH2F *h2) {
	float flex;
	float *flexArray =0;
	int nmod = 3;
	
	int nstep=h2->GetYaxis()->GetNbins();
	Double_t mi=h2->GetYaxis()->GetXmin();
	Double_t ma=h2->GetYaxis()->GetXmax(); 
	float min = 330;  
	
	Double_t mypar[5];
	Double_t emypar[5];
	
	for(int ichan=0; ichan<NCHAN*NCHIP*nmod; ichan++) {
		TH1F *hchan = new TH1F("hchan", "", nstep, mi, ma);		
		hchan = getCh(h2,ichan); //I start  failing here
		flex = FitERF4(hchan,min, mypar, emypar,1); // also here
		flexArray[ichan] = flex;
		delete hchan;		
	}
	return flexArray;
}

The culprit are the following:

Root > Function getCh() busy flag cleared
Function flexpoint() busy flag cleared

Details:


 *** Break *** segmentation violation
Attaching to program: /proc/7589/exe, process 7589
warning: .dynamic section for "/lib/libdl.so.2" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libstdc++.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/lib/libm.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/lib/libgcc_s.so.1" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/lib/libpthread.so.0" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXrender.so.1" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXinerama.so.1" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXext.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXau.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXdmcp.so.6" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXcursor.so.1" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
warning: .dynamic section for "/usr/lib/libXfixes.so.3" is not at the expected address
warning: difference appears to be caused by prelink, adjusting expectations
[Thread debugging using libthread_db enabled]
0x00bdf402 in __kernel_vsyscall ()
#1  0x069dccb3 in __waitpid_nocancel () from /lib/libc.so.6
#2  0x0698162b in do_system () from /lib/libc.so.6
#3  0x00386f3d in system () from /lib/libpthread.so.0
#4  0x006d0477 in TUnixSystem::Exec(char const*) () from /users/root_v5.20/lib/libCore.so
#5  0x006d5f01 in TUnixSystem::StackTrace() () from /users/root_v5.20/lib/libCore.so
#6  0x006d2b46 in TUnixSystem::DispatchSignals(ESignals) () from /users/root_v5.20/lib/libCore.so
#7  0x006d2bd4 in SigHandler(ESignals) () from /users/root_v5.20/lib/libCore.so
#8  0x006d1e19 in sighandler(int) () from /users/root_v5.20/lib/libCore.so
#9  <signal handler called>
#10 0x027f35eb in G__G__Hist_107_0_79(G__value*, char const*, G__param*, int) () from /users/root_v5.20/lib/libHist.so
#11 0x00c1c2e3 in Cint::G__ExceptionWrapper(int (*)(G__value*, char const*, G__param*, int), G__value*, char*, G__param*, int) () from /users/root_v5.20/lib/libCint.so
#12 0x00c2e7a2 in G__exec_asm () from /users/root_v5.20/lib/libCint.so
#13 0x00c31f26 in G__exec_bytecode () from /users/root_v5.20/lib/libCint.so
#14 0x00c92228 in G__interpret_func () from /users/root_v5.20/lib/libCint.so
#15 0x00c80966 in G__getfunction () from /users/root_v5.20/lib/libCint.so
#16 0x00c64e70 in G__getitem () from /users/root_v5.20/lib/libCint.so
#17 0x00c67abb in G__getexpr () from /users/root_v5.20/lib/libCint.so
#18 0x00c6d55d in G__getexpr () from /users/root_v5.20/lib/libCint.so
#19 0x00cdab4f in G__exec_statement () from /users/root_v5.20/lib/libCint.so
#20 0x00ce612a in G__exec_loop () from /users/root_v5.20/lib/libCint.so
#21 0x00ce5a3b in G__exec_statement () from /users/root_v5.20/lib/libCint.so
#22 0x00c93a8b in G__interpret_func () from /users/root_v5.20/lib/libCint.so
#23 0x00c80966 in G__getfunction () from /users/root_v5.20/lib/libCint.so
#24 0x00c64e70 in G__getitem () from /users/root_v5.20/lib/libCint.so
#25 0x00c67abb in G__getexpr () from /users/root_v5.20/lib/libCint.so
#26 0x00c572e4 in G__define_var () from /users/root_v5.20/lib/libCint.so
#27 0x00ce2a67 in G__exec_statement () from /users/root_v5.20/lib/libCint.so
#28 0x00c52c68 in G__exec_tempfile_core () from /users/root_v5.20/lib/libCint.so
#29 0x00c53fa3 in G__exec_tempfile_fp () from /users/root_v5.20/lib/libCint.so
#30 0x00cebb2c in G__process_cmd () from /users/root_v5.20/lib/libCint.so
#31 0x006bf8db in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /users/root_v5.20/lib/libCore.so
#32 0x00604a16 in TApplication::ProcessLine(char const*, bool, int*) () from /users/root_v5.20/lib/libCore.so
#33 0x00238e9a in TRint::HandleTermInput() () from /users/root_v5.20/lib/libRint.so
#34 0x002374f0 in TTermInputHandler::Notify() () from /users/root_v5.20/lib/libRint.so
#35 0x0023978e in TTermInputHandler::ReadNotify() () from /users/root_v5.20/lib/libRint.so
#36 0x006cee02 in TUnixSystem::CheckDescriptors() () from /users/root_v5.20/lib/libCore.so
#37 0x006d3024 in TUnixSystem::DispatchOneEvent(bool) () from /users/root_v5.20/lib/libCore.so
#38 0x0065c8bc in TSystem::InnerLoop() () from /users/root_v5.20/lib/libCore.so
#39 0x0065c683 in TSystem::Run() () from /users/root_v5.20/lib/libCore.so
#40 0x00604b02 in TApplication::Run(bool) () from /users/root_v5.20/lib/libCore.so
#41 0x00237c6e in TRint::Run(bool) () from /users/root_v5.20/lib/libRint.so
#42 0x08048d83 in main ()
A debugging session is active.

        Inferior 1 [process 7589] will be detached.

Quit anyway? (y or n) [answered Y; input not from terminal]
Detaching from program: /proc/7589/exe, process 7589
Root > Function getCh() busy flag cleared
Function flexpoint() busy flag cleared

Compiling with filename.C++, no complains to my buggy program was noted. Any suggestions how to fix this?

F.

Hi,

Does the crash exist also when you compile (i.e. I suspect a CINT bug)?

Philippe.

No, it does not crash

This looks really weird … float *flexpoint(TH2F *h2) { // ... float *flexArray =0; // ... for(int ichan=0; ichan<NCHAN*NCHIP*nmod; ichan++) { // ... flexArray[ichan] = flex; // ... } return flexArray; } I would say you need something like: float *flexArray = new float[(NCHAN*NCHIP*nmod)]; // ... and afterwards, when you no longer need it ... delete[] some_flexArray_pointer_returned_once_by_flexpoint;
Also, in the “FitERF4” function you “delete func” … I’m not sure if you are allowed to do this, as the “h1” histogram uses it (as its “fitfunc”).

Thanks, but in the loop

for(int ichan=0; ichan<NCHAN*NCHIP*nmod; ichan++) {
      TH1F *hchan = new TH1F("hchan", "", nstep, mi, ma);      
      hchan = getCh(h2,ichan); //I start  failing here    
      ......//forget about the other lines
      delete hchan;      
   }

while if I do

	M1:
	if(ichan>=chMin && ichan<chMax) { 
                        TH1F *hchan = new TH1F("hchan", "", nstep, mi, ma); 
			hchan = getCh(h2, ichan); //this seems to work
			c1->Modified();				
			c1->Update();
			usleep(70000);
			delete hchan;			
			
	}
        ichan++;
	if (ichan  <= chMa+1)
			goto M1;

which looks funny

Well, this looks weird … TH1F *hchan = new TH1F("hchan", "", nstep, mi, ma); // you create a new "hchan" histogram hchan = getCh(h2,ichan); // you OVERWRITE THE POINTER with a pointer to "h1" (returned by "getCh") // the pointer to the "hchan" histogram, created in the first line above, is "lost" (a memory leak) delete hchan; // you delete "h1" (that was created in "getCh") Try with: TH1F *hchan = getCh(h2,ichan); // the hchan pointer will point to the "h1" histogram (created in "getCh") // ... delete hchan; // delete "h1" (that was created in "getCh")

It is a good point, Wile. Thanks. But it does not address my main problem

Root > Function getCh() busy flag cleared
Function flexpoint() busy flag cleared

see above…

How about you pack your source code and your data so that I can try it myself?

What are the values of NCHAN and NCHIP? Is ichan exceeding h2->GetNbinsX()?

A simple if statement in getCh() whould indicate where the issue is and avoid the seg fault.

for (int i=1; i<nstep+1; i++) { 
   if (chan+1 <= h2->GetNbinsX() && i <= h2->GetNbinsY())
      h1->SetBinContent(i, h2->GetBinContent(chan+1,i));    
   else
      fprintf(stderr,"ERROR: Unknown bin %d %d",chan+1,i);
}

Both methods, TH1F::SetBinContent and TH2F::GetBinContent, are internally protected against “incorrect” bin numbers (there should be no case in which they cause any segmentation fault).

This is true. Although, one might waste time though creating histograms that don’t have a corresponding bin in the TH2.

I do see a different issue. You define a pointer flexArray and then use it like an array flexArray[ichan] = flex; This will most definitely lead to a segmentation fault.

Also, why don’t you use GetParErrors() in FitERF4(), instead of getting each value one at a time? fitfunc->GetParErrors(emypar);