Can't access an specific place in a 3 dimensional array
Can't access an specific place in a 3 dimensional array
First of all, I'm using the ROOT libraries, and there is a ROOT forum, but I don't think this is a problem with ROOT specifically..
Now, I have a 3 dimensional array of 2 dimensional Histograms all_histos (histograms are objects in ROOT), and their size depends on some arrays that I want to be able to change in the future:
//this are the arrays
double pT_range = {8, 4, 2, 1, 0.5}; //multiplicity ranges
double Aj_range = {0.22, 0, 0};
double mult_range = {234, 204, 188, 168, 152, 140, 128, 116, 104, 92, 76, 0}; //multiplicity ranges
//this is the first array of histograms
TH2D* all_histos[getSize(Aj_range)][getSize(pT_range)][getSize(mult_range)];
I have to initialize them and fill them with data, there's no problem there.
Then I extract some data from them and save that new data in other array of histograms hist_final and save them, I can see them they are correct.
TH1D* hist_final[getSize(Aj_range)][getSize(pT_range)][getSize(mult_range)];
for (int a = 0; a < getSize(Aj_range); ++a)
{
for (int p = 0; p < getSize(pT_range); ++p)
{
for (int m = 0; m < getSize(mult_range); ++m)
{
for (int n = 0; n < 9; ++n)
{
all_histos[a][p][m]->GetXaxis()->SetRangeUser( 0.2*n, 0.2*(n+1) );//we first define each ring
hist_final[a][p][m]->SetBinContent( n+1, all_histos[a][p][m]->GetMean(2) ); //then take the average in that ring
hist_final[a][p][m]->SetBinError( n+1, all_histos[a][p][m]->GetMeanError(2) );
}
}
}
}
All of this works
Then I wanted to add some new historgams with slightly different data, so I decide to increase the dimension of hist_final in the second coordinate by 1:
TH1D* hist_final[getSize(Aj_range)][getSize(pT_range)+1][getSize(mult_range)];
and then I proceeded to fill those histograms with the slightly different data, only to get a Segmentation Violation.
for (int a = 0; a < getSize(Aj_range); ++a)
{
for (int m = 0; m < getSize(mult_range); ++m)
{
for (int p = 1; p < getSize(pT_range); ++p)
{
all_histos[a][0][m]->Add(all_histos[a][p][m],1);
}
for (int n = 0; n < 9; ++n)
{
all_histos[a][0][m]->GetXaxis()->SetRangeUser( 0.2*n, 0.2*(n+1) );//we first define each ring
hist_final[a][getSize(pT_range)][m]->SetBinContent( n+1, all_histos[a][0][m]->GetMean(2) ); //then take the average in that ring
hist_final[a][getSize(pT_range)][m]->SetBinError( n+1, all_histos[a][0][m]->GetMeanError(2) );
}
}
}
I thought that it could be many things, and I started to rule them out:
all_histos[a][0][m]->GetMean(2)
is a double, so is
all_histos[a][0][m]->GetMeanError(2)
they, are not the problem, then I thought aboyt the bins, but if I save the histograms without filling them I can open them and see how many bins they've got, they have 9, that's not the problem.
I eventually found out that it was in
hist_final[a][getSize(pT_range)][m]
If I change
getSize(pT_range)
for 0 1 2 3 or 4 there's no problem, although that's overwriting useful data. Remember that I used:
TH1D* hist_final[getSize(Aj_range)][getSize(pT_range)+1][getSize(mult_range)];
to create this array, it should have 6 places from 0 to 5. So I said "fuck it"
TH1D* hist_final[getSize(Aj_range)][500][getSize(mult_range)];
who cares how big it is, I'll never use the extra space, the important things is that it works.
BUT IT DOESN'T. IT STILL FAILS AT 5 AND NUMBERS GRATER THAN 5.
I have no idea why, but if I change the second coordinate for any integer smaller than 5 the code works, I tried putting by hand many combinations of of values for the coordinates, only those where the second is 5 fail.
Because of this I know that the problem is that coordinate, but for the life of me I can't figure out why, nor how to solve it.
My last idea was that the pointers may be the problem somehow, I run my code in a Cluster, so I logged out which should delete all temporary memory I was using, entered again sent my code and ran it only to find the same problem.
I'm out of ideas. Thanks.
You can see my whole code here
hist_final
2 Answers
2
Segmentation faults are usually because you are trying to access a place in memory that you can't.
In this line of code:
hist_final[a][getSize(pT_range)][m]
the 2nd field should probably be :
hist_final[a][getSize(pT_range) - 1 ][m]
If you want the last element in hist_final
(the 2nd dimension of the array). I'm not sure which element you want but pT_range is 5 and as you stated, valid inputs in this field are 0-4.
hist_final
The question is quite old, but maybe my answer to that can be useful to others. It might be that you are just out of the standard memory space for ROOT (how large are your histograms?).
As far as I understand, you just create pointers such as TH2D* all_histos
, but you do not allocate memory for them, as you would do by using
TH2D* all_histos
TH2D**** all_histos = new TH2D***[getSize(Aj_range)];
for (int a = 0; a < getSize(Aj_range); a++)
{ all_histos[a] = new TH2D***[getSize(pT_range)];
for (int a = 0; a < getSize(Aj_range); p++)
{ all_histos[a][p] = new TH2D**[getSize(mult_range)];
}
}
As a matter of fact, the pre-allocated memory (on the stack) for the ROOT-framework is not huge (I think 64 MB). If you allocate memory with the 'new' command, you can go above this limit.
By the way, I think at some point you are also mixing up 'getSize(Aj_range)' and 'getSize(mult_range)' in the indices.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
When you change the size of your
hist_final
array, do you also change the initialization code to properly initialize those additional elements?– 1201ProgramAlarm
Feb 28 at 1:42