On Wed, 21 Aug 2002 14:35:45 -0400
"William Love" <love@bnl.gov> wrote
concerning "[ROOT] Arrays of 2D histograms":
> Hello root
> I want to divide track data among identical TH2D's according to
> for example, the vertex z. This would be easiest if I could make and
> address an array of TH2D's I tried:
>
> *** Start at Date : Wed Aug 21 14:10:58 2002
> QAInfo:You are using STAR_LEVEL : dev, ROOT_LEVEL : 3.02.07 and node :
> rcas6006.rcf.bnl.gov
> root.exe [0] TH2D Same[8]("b","b",50, 0, 10, 50, 0, 10)
First off, this is not valid C++. To test if something is valid, try
and compile it properly e.g., doing:
root [0] .x foo.C++
(Hi Rene :-) You'll see the error:
initializing array with parameter list
So far so good. Now, taking out the parameter list, like
TH2D same[8];
still leaves you with a problem though it OK C++.
> root.exe [1] Same[2].SetName("number3")
>
> *** Break *** segmentation violation
>
The problem is, that you initialise each elment of the array with the
default constructor (CTOR), which does not do all the allocations you
need.
> Where do I go wrong?
You need to use a named CTOR and specify all the stuff you need to.
One way of doing this, is to have a pointer to a pointer array:
// Allocate memory for 8 pointers, each pointing to a TH2D.
// (this is 8 long's, so it isn't as bad as it looks)
TH2D** same = new TH2D*[8];
// Now we need to initialise each pointer in turn
for (Int_t i = 0; i < 8; i++)
same[i] = new TH1D(Form("same%02d", i), Form("same%02d", i),
50, 0, 10, 50, 0, 10);
// Do some work
....
for (Int_t i = 0; i < 8; i++)
same[i]->Fill(x[i], y[i], w[i]);
// Now we want to deallocate the array. We have to free the memory
// of each pointer explicitly, or we're in trouble.
for (Int_t i = 0; i < 8; i++)
delete same[i];
// And finally we free the 8 pointers:
delete same;
Now, if you think this looks ugly and are about to say `Hay, that
was easier in Fortran', it's because you're partially right. The
thing to remember is, that C++ (inheriting it from C) is intrinsicly
bad at handling arrays. Instead, one would either implement a
specialised class (TList, TObjArray, ...) or use a templated class,
like and STL container. The latter is probably the best thing to do:
std::vector<TH2D*> same;
same[0] = new TH2D(...);
This is acually much safer (less error prone) than the double pointer
stuff above. The choice of STL container depends on what you want to
do - check out the SGI STL documentation that probably ships with your
favorite Linux distribution.
> I was up all night wondering where the sun went, then it dawned on me.
Don't you just hate that?
Yours,
____ | Christian Holm Christensen
|_| | -------------------------------------------------------------
| | Address: Sankt Hansgade 23, 1. th. Phone: (+45) 35 35 96 91
_| DK-2200 Copenhagen N Cell: (+45) 24 61 85 91
_| Denmark Office: (+45) 353 25 305
____| Email: cholm@nbi.dk Web: www.nbi.dk/~cholm
| |
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:51:05 MET