# Correct way to write a function that return an n-dimensional array of TH1 objects

Hello,

I’m trying to write a function that return an array of TH1D histograms.
I follow a post on stackoverflow, which recommended using malloc to create the array of histograms. I follow the instruction and my code works.
The code I wrote is as follow:

``````TH1D** *array_of_hists( )
{
TH1D** *hist = ( TH1D*** )malloc( sizeof(TH1D**)*2 );
for ( int i=0; i<2; i++ )
{
hist[i] = ( TH1D** )malloc( sizeof(TH1D*)*5 );
for ( int j=0; j<2; j++ )
{
std::string hist_name = Form ( "hist_%d_%d", i, j );
hist[i][j] = new TH1D( hist_name.data( ), "", 20, -5, 5 );
hist[i][j] -> FillRandom( "gaus", 10000 );
}
}
return hist;
}

int test_TH1_array( )
{
system( "mkdir -p Plot" );
TH1D** *hist = array_of_hists( );
for ( int i=0; i<2; i++ )
for ( int j=0; j<2; j++ )
{
TCanvas *canvas = new TCanvas( "canvas", "", 600, 400 );
canvas -> cd( );
hist[i][j] -> SetLineColor( kOrange+7 );
hist[i][j] -> SetLineWidth( 2 );
hist[i][j] -> Draw( "hist" );
canvas -> SaveAs( Form( "Plot/plot_%d_%d.png", i, j ) );
delete canvas;
}
return 0;
}
``````

Though the program runs fine, I still didn’t understanding my code well. When I remove the asterisk(s) in the malloc function:

``````TH1D** *hist = ( TH1D*** )malloc( sizeof(TH1D)*2 );
``````

It still works, and the result looks ok, although I expected an seg fault from the missing asterisks.

1. Why the missing asterisk does not affect my result?
2. Which is the correct way to define the array of histogram using malloc?

Thank you very much,
Hoa

ROOT Version: ROOT6.24/00
Platform: Ubuntu 18.04
Compiler: Not Provided

Hi @LongHoa,

I guess that you are referring to a couple of asterisks you removed in `sizeof(TH1D**)`. The rest of the explanation will just assume that.
In the code above, the original line allocates enough space on the heap (via `malloc()`) to hold an array of 2 pointers. If you remove the those, you will allocate space for storing 2 `TH1D` instances. As long as the size of a `TH1D` object is greater than the size of a pointer -which it certainly is-, the allocation will be large enough for the expected usage. Therefore, in this case, you are reserving slightly more memory (while using just a few bytes at the beginning of the region).

Replied above; no expected segfault, as you are just using the first few bytes of a larger allocation; no unintended misuse or data corruption.

The code above is actually creating an array of pointers to arrays, which is not the same as a n-dimensional array in row-major (C) order.
I would simplify the code a lot -which also makes it more efficient-, by allocating space for `N` objects, and being `N` the total number of `TH1D` objects (i.e., a linear array).

Cheers,
J.

1 Like