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