Re: [ROOT] Segmentation violation when reading a TMatrix object

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Mon Jul 23 2001 - 19:36:56 MEST


Hi Georges, 

On Mon, 23 Jul 2001 17:26:19 +0200 (CEST)
Georges Lobo <lobo@irmm.jrc.be> wrote
concerning ": [ROOT] Segmentation violation when reading a TMatrix object":
> Hi rooters,
> I have a small problem with the reading of a TMatrix object stored
> in a  file.
>
1 > //example.C
2 > {
3 >   f = new TFile("th232.root");
4 >   f->ls();
5 >   accordeon->Print();
6 >   for(int i=0;i<5;i++) 
7 >     cout << accordeon(i,0) << endl;
8 > }
> 
> When I run the example I have a segmentation violation but I don't
> understand why.

It's probably because you're mixing things a bit.   See, accordeon is
a pointer, or at least you're using it as a pointer in line 5, by
derefencing it with "->".  However, in line 7 you're using it as an
object, by (presumably) sending the message TMatrixD::operator()(Int_t
i, Int_t j).  But, since accordeon is a pointer, line 7 is not
understood as the message above, but probably as an initialisation, so
in fact you've changed the size of accordion to 1x0, or something like
that. To send that message, you _must_ do 

7'       cout << accordeon->operator()(i, 0) << endl;
 
Here's a small example I ran: 

  prompt% root 
  root [0] TFile* file = new TFile("foo.root", "RECREATE")
  root [1] TMatrixD a(5, 2) 
  root [2] for (Int_t i = 0; i < 5; i++) a(i, 0) = i  
  root [3] for (Int_t i = 0; i < 5; i++) a(i, 1) = i * 10 
  root [4] a.Print()

  Matrix 5x2 is as follows
  
       |        0  |        1  |
  ------------------------------------------------------------------
     0 |          0           0 
     1 |          1          10 
     2 |          2          20 
     3 |          3          30 
     4 |          4          40 

  root [5] a.Write("a")
  (Int_t)186
  root [6] file->Write()
  (Int_t)0
  root [7] file->Close()
  root [8] .q

And then 

  prompt% root 
  root [0] TFile* file = TFile::Open("foo.root")
  root [1] gDirectory->ls()
  TFile**		foo.root	
   TFile*		foo.root	
    KEY: TMatrixD	a;1	Matrix class (double precision)
  root [2] a
  (const class TMatrixD*const)0x8694630
  root [3] a->Print()

  Matrix 5x2 is as follows

       |        0  |        1  |
  ------------------------------------------------------------------
     0 |          0           0 
     1 |          1          10 
     2 |          2          20 
     3 |          3          30 
     4 |          4          40 
  
  root [4] for (Int_t i = 0; i < 5; i++) cout << a->operator()(i,0) << endl
  0
  1
  2
  3
  4
  root [5]  for (Int_t i = 0; i < 5; i++) cout << a(i,0) << endl            
  0

   *** Break *** segmentation violation
  Root > .q 

As you see in line [2] above, a is indeed a pointer to a TMatrixD
object, not a reference or an object, so you are forced to use the
explicit message operator()(Int_t i, Int_t j) as in line [4] above. 

The fact that CINT unfortunatly allows you to mix and mingle "." and
"->" should not prompt you to pursue that bad habit.  Always use "->"
for pointers and "." for references or objects.  Do not mix the two -
it'll cause you more trouble in the end. 

Yours, 

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



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