Re: Access objects inheriting from TAttLine via TAttLine pointer

From: Thomas Lauf <thl_at_hll.mpg.de>
Date: Mon, 6 Feb 2012 12:11:40 +0100


Hello Axel, hello Timur,

thanks a lot for the hint. Use of dynamic_cast solved this problem for me. Guess I am too used to the c-like casting which worked perfectly - until now... :)

Regards, Thomas

Axel Naumann wrote:

> Hi Thomas,
> 
> What Timur meant (but because it's obvious to him didn't mention :-) is
> that you should use dynamic_cast<TAttLine*>. You might run into problems
> with CINT, though - so alternatively you can try to get
> TClass::DynamicCast
> <http://root.cern.ch/root/html/TClass#TClass:DynamicCast> to do the same
> job:
> 
> 
>    TObject* obj = 0;
>    while( (obj = Next()) ) {
>      TAttLine* attLine = (TAttLine*)
> obj->IsA()->DynamicCast(TAttLine::Class(), obj)
>      cout << attLine->GetLineColor() << endl;
>    }
> 
> Cheers, Axel.
> 
> 
> Timur Pocheptsov wrote on 02/06/2012 11:23 AM:

>> I do not know, what's inside TObjArray::Print, but I know, that TAttLine does not inherit TObject,
>> so what you do in your cast is equal to reinterpret_cast, which is wrong in case of multiple inheritance. So, this is the code with undefined behavior.
>> ________________________________________
>> From: owner-roottalk_at_root.cern.ch [owner-roottalk_at_root.cern.ch] on behalf of Thomas Lauf [thl_at_hll.mpg.de]
>> Sent: 06 February 2012 11:15
>> To: roottalk (Mailing list discussing all aspects of the ROOT system.)
>> Subject: [ROOT] Access objects inheriting from TAttLine via TAttLine pointer
>>
>> Hello ROOTers,
>>
>> I like to access different objects which all inherit from TAttLine. As a
>> simple example of what I want to do, take the following script where all
>> objects are actually TLine instances:
>>
>> void TLineTest()
>> {
>> TObjArray Array;
>>
>> Array.Add( new TLine( 0, 0, 1, 1 ) );
>> Array.Add( new TLine( 0, 0, 1, 1 ) );
>> Array.Add( new TLine( 0, 0, 1, 1 ) );
>>
>> TLine* Line;
>> Int_t i=0;
>>
>> Array.Print();
>>
>> TIter Next( &Array );
>>
>> while( (Line = (TLine*) Next()) ) {
>> cout << Line->GetLineColor() << endl;
>> }
>>
>> Array.Print();
>>
>> }
>>
>> The output is, as expected, the content of the list, then three times 1
>> (the line color) and, again, the output of the list.
>>
>> Now I want to apply this scheme to a list containing different objects
>> which all inherit from the TAttLine class:
>>
>> void TAttLineTest()
>> {
>> TObjArray Array;
>>
>> Array.Add( new TH1I( "foo", "bar", 0, 0, 0 ) );
>> Array.Add( new TLine( 0, 0, 1, 1 ) );
>> Array.Add( new TGraph(1) );
>>
>> TAttLine* AttLine;
>> Int_t i=0;
>>
>> Array.Print();
>>
>> TIter Next( &Array );
>>
>> while( (AttLine = (TAttLine*) Next()) ) {
>> cout << AttLine->GetLineColor() << endl;
>> }
>>
>> Array.Print();
>>
>> }
>>
>> The script is analog to the example above, but now I use a TAttLine
>> pointer to access the objects in the array. Running this script leads to
>> a segmentation fault with the following output (with ROOT 5.32):
>>
>> bash-3.2$ root -x -q TAttLineTest.C
>> *******************************************
>> * *
>> * W E L C O M E to R O O T *
>> * *
>> * Version 5.32/00 2 December 2011 *
>> * *
>> * You are welcome to visit our Web site *
>> * http://root.cern.ch *
>> * *
>> *******************************************
>>
>> ROOT 5.32/00 (tags/v5-32-00_at_42375, Jan 24 2012, 13:07:59 on linuxx8664gcc)
>>
>> CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
>> Type ? for help. Commands must be C++ statements.
>> Enclose multiple statements between { }.
>> root [0]
>> Processing TAttLineTest.C...
>> Collection name='TObjArray', class='TObjArray', size=16
>> TH1.Print Name = foo, Entries= 0, Total sum= 0
>> TLine X1=0.000000 Y1=0.000000 X2=1.000000 Y2=1.000000
>> x[0]=0, y[0]=0
>> 0
>> 0
>> 0
>> Collection name='TObjArray', class='TObjArray', size=16
>>
>> *** Break *** segmentation violation
>>
>> [...]
>>
>> ===========================================================
>> #10 0x00000032d70bdb65 in __dynamic_cast () from /usr/lib64/libstdc++.so.6
>> #11 0x00002ab7e684f42e in TCollection::PrintCollectionEntry
>> (this=0x171e3200,
>> entry=0x17266360, option=0x2ab7e6cd039b "", recurse=0)
>> at /sirius/thl/root/core/cont/src/TCollection.cxx:307
>> #12 0x00002ab7e684efef in TCollection::Print (this=0x171e3200,
>> option=0x2ab7e6cd039b "", recurse=1)
>> at /sirius/thl/root/core/cont/src/TCollection.cxx:357
>> #13 0x00002ab7e684df13 in TCollection::Print (this=0x171e3200,
>> option=0x2ab7e6cd039b "")
>> at /sirius/thl/root/core/cont/src/TCollection.cxx:334
>> ===========================================================
>>
>> Somehow, accessing the objects via the TAttList pointer corrupts the
>> array. Does anyone know why? I also wonder why the color of the TLine
>> object in the list is now '0'...
>>
>> I've tested this script also on ROOT 5.30 and 5.26 with the same result.
>>
>> Regards, Thomas
>>
>>
>>

>
-- 
Dipl.Phys. Thomas Lauf
MPI Halbleiterlabor
Otto-Hahn-Ring 6
81739 Muenchen

Tel. : +49 89 839400 - 93
Fax. : +49 89 839400 - 13
Received on Mon Feb 06 2012 - 12:11:59 CET

This archive was generated by hypermail 2.2.0 : Tue Feb 07 2012 - 23:50:01 CET