Re: [ROOT] Array of TH1F

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Mon Oct 22 2001 - 13:35:29 MEST


Hi David, 

On Fri, 19 Oct 2001 18:07:09 +0200
Lindelöf David <David.Lindelof@cern.ch> wrote
concerning "[ROOT] Array of TH1F":
> Rooters,
> 
> Why oh why will this work:

It's illegal C++. 
 
> TH1F *hclus;
> hclus=new TH1F[64];

Here, you actually initialise 64 TH1F object with the default
constructor, 

> hclus[9].TH1F("name","descr",100,0,1000);

And then you try to reinitialise the 10'th objects - really bad and
not legal.  CINT should barf at you - if it doesn't it's a limitation
of CINT. 

> but not this:
> 
> hclus[9].Fill(1);
>
> and yield a segmentation fault?

That's because the proper array size is not set, since you've
initialised the hclus[9] with the default constructor.  Hence you try
to access the invalid memory, leading to the SIGSEGV. 
 
Below I've made a small C++ program that illustrates the illegalness
of you code.  Try and compile it with and without the lines marked.
With the lines marked, it will not compile; without it will. Try
running the program, and you'll see the use of the default CTOR quite
clearly. 

<<< Beginning of example <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  // 
  // Build the program with (using GCC) 
  //    
  //   g++ foo.cc -o foo 
  // 
  #ifndef __IOSTREAM__
  #include <iostream>
  #endif
  
  class Foo 
  {
  private:
    int fFoo;
  public:
    Foo() : fFoo(0) { cout << "Foo::Foo(void) [" << fFoo << "]" << endl; }
    Foo(int foo) : fFoo(foo) { 
      cout << "Foo::Foo(int) [" << fFoo << "]" << endl; }
    
  };

  int main(int argc, char** argv) 
  {
    // This sends the message Foo::Foo(void) three times 
    Foo* bad = new Foo[3];
  
    // This is illegal, since it reinitialised the bad objects. 
    // Comment out the next 3 lines to make the code compile.  With the
    // next three lines it will not compile. 
    bad[0].Foo(1);
    bad[1].Foo(2);
    bad[2].Foo(3);
  
    // This does not send any message to Foo objects, but says that
    // memory should be reserved for three pointers to Foo objects at
    // the address of ok. 
    Foo** ok = new Foo * [3];
    
    // Really initialise and allocate memory for the three objects 
    ok[0]    = new Foo(1);
    ok[1]    = new Foo(2);
    ok[2]    = new Foo(3);
  
    return 0;
  }
<<< End of example <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Hope that clearifies things. 

Yours, 

Christian Holm Christensen -------------------------------------------
Address: Sankt Hansgade 23, 1. th.           Phone:  (+45) 35 35 96 91 
         DK-2200 Copenhagen N                Cell:   (+45) 28 82 16 23
         Denmark                             Office: (+45) 353  25 305 
Email:   cholm@nbi.dk                        Web:    www.nbi.dk/~cholm

    



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:03 MET