Re: [ROOT] Memory leak when using TClonesArray::ExpandCreate

From: Frankland John (frankland@ganil.fr)
Date: Thu Jul 24 2003 - 13:07:36 MEST


Hi Rene

I still have exactly the same problem even after checking my .rootrc
I don't know what I've done wrong.
Also, the fact that when I seg fault I get

/usr/bin/c++filt: unknown demangling style `gnu-new-abi'

instead of a stack trace isn't helping much either. Can you tell me why 
this is ?
I have
GNU c++filt (C++ demangler), version 3.2
g++ (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
on my machine.

Thanks a lot
John

Rene Brun wrote:

>Hi John,
>
>I cannot reproduce your problem. Here is a transcript of my session.
>
>Rene Brun
>
>root [0] gSystem.Load("libPhysics")
>(int)0
>root [1] .L MyNuc.cxx+
>Info in <TUnixSystem::ACLiC>: creating shared library
>/home/brun/roottest/./MyNuc_cxx.so
>root [2] .L test.C+
>Info in <TUnixSystem::ACLiC>: creating shared library
>/home/brun/roottest/./test_C.so
>root [3] test()
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>Creating object list....
>done
>fNb_Objects=1, size of list=1
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
>fNb_Objects=6, size of list=6
>fNb_Objects=6, size of list=6
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
> ++ Calling default ctor ++
>Calling AddToObjList...
>AddToObjList............
>done
>fNb_Objects=8, size of list=6
>root [4] .q
>
>
>Frankland John wrote:
>  
>
>>Hello Rene
>>
>>Rene Brun wrote:
>>
>>    
>>
>>>Hi John,
>>>
>>>You are not drawing the right conclusion from your observation
>>>with MyNuc::GetNbObj. Let me explain.
>>>
>>>The TClonesArray is based on the standard C++ "new with placement".
>>>When calling new(a[i]) myclass(), the following happens:
>>> -if a[i] is null, an object of myclass is allocated space and the
>>>myclass
>>>constructor is called.
>>> - if a[i] is not null, your myclass constructor is called. No need to
>>>allocate space (time consuming). The object is simply initialized by the
>>>statements in your constructor, overwriting the values of the data
>>>members
>>>created by a previous call to the constructor. The address of the object
>>>is the one previously stored at a[i] (new with placement).
>>>In your case your class MyNuc records only the number of calls
>>>to your myclass constructor. It does not record the number of times
>>>a new object has been allocated.
>>>
>>>
>>>
>>>
>>>      
>>>
>>In order to see this happening, I modified the MyNuc class as in the
>>attachment.
>>I added a static TList to which I add the "this" pointer every time the ctor
>>is called, only if
>>the object pointed to is not already in the list. However, despite protecting
>>all possible
>>cases of pointer abuse, when I compile and run the test.C script attached (.L
>>libPhysics.so,
>>.L MyNuc.cxx+, then .L test.C+) it ends up in a segmentation fault:
>>
>>root [0] .L libPhysics.so
>>root [1] .L MyNuc.cxx+
>>Info in <TUnixSystem::ACLiC>: creating shared library
>>/home/john/lib//home/john/ClonesTests/./MyNuc_cxx.so
>>root [2] .L test.C+
>>root [3] test()
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>Creating object list....
>>done
>>fNb_Objects=1, size of list=1
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>done
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>done
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>done
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>done
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>done
>>fNb_Objects=6, size of list=6
>>fNb_Objects=6, size of list=6
>> ++ Calling default ctor ++
>>Calling AddToObjList...
>>AddToObjList............
>>
>> *** Break *** segmentation violation
>> Generating stack trace...
>>/usr/bin/c++filt: unknown demangling style `gnu-new-abi'
>>
>>I can't see why ! Can somebody please help me ?
>>My last CVS update/compile was July 14th, on Linux RH8 with gcc3.2.
>>
>>Thanks a lot
>>John
>>
>>--
>>
>>                     [ganil logo]
>>
>>                     John D. Franklandtel: +33
>>                     Beam Coordinator (0)231454628
>>                     GANIL            fax: +33
>>                     B.P. 55027       (0)231454665
>>                     14076 CAEN Cedex
>>                     05
>>
>>    -----------------------------------------------------------------------
>>#ifndef __MyNuc_H
>>#define __MyNuc_H
>>
>>#include "TLorentzVector.h"
>>
>>class MyNuc : public TLorentzVector
>>{
>>                        UChar_t fZ;
>>                        UChar_t fA;
>>                        static Int_t fNb_Objects;
>>                        static TList* fObjList;
>>                        void AddToObjList(TObject*);
>>
>>        public:
>>                        MyNuc();
>>                        MyNuc(const MyNuc &);
>>                        MyNuc(int z, int a);
>>                        virtual ~MyNuc();
>>
>>                        void SetZ(int z){fZ=(UChar_t)z;}
>>                        void SetA(int a){fA=(UChar_t)a;}
>>                        Int_t GetZ() const;
>>                        Int_t GetA() const;
>>                        Int_t GetNbObj(Option_t *opt="");
>>                        void SetPxPyPz(Float_t px, Float_t py, Float_t pz);
>>                        void Clear(Option_t *opt="");
>>
>>                        ClassDef(MyNuc,1) // Just for tests
>>};
>>
>>#endif
>>
>>    -----------------------------------------------------------------------
>>#include "MyNuc.h"
>>#include <Riostream.h>
>>
>>ClassImp(MyNuc)
>>
>>//__________________________________________________________________
>>//MyNuc
>>//For testing TClonesarray behaviour
>>//
>>
>>Int_t MyNuc::fNb_Objects=0;
>>TList *MyNuc::fObjList=0;
>>
>>MyNuc::MyNuc()
>>{
>>        cout << " ++ Calling default ctor ++ " << endl;
>>        fZ = fA = 0;
>>        fNb_Objects++;
>>        cout << "Calling AddToObjList..." << endl;
>>        AddToObjList(this);
>>}
>>
>>void MyNuc::AddToObjList(TObject* obj)
>>{
>>        //Add pointer to object to static list if the pointer is not already in the list
>>        cout << "AddToObjList............" << endl;
>>        if(!fObjList) {
>>                cout << "Creating object list...." << endl;
>>                fObjList=new TList;
>>        }
>>        if(obj){
>>                if(!fObjList->FindObject(obj)) fObjList->Add(obj);
>>        } else {
>>                cout << "(the 'this' pointer is NULL)........."  << endl;
>>        }
>>        cout << "done" << endl;
>>}
>>
>>MyNuc::MyNuc(int z, int a)
>>{
>>        fZ = (UChar_t)z;
>>        fA = (UChar_t)a;
>>        fNb_Objects++;
>>        AddToObjList(this);
>>}
>>
>>MyNuc::MyNuc(const MyNuc &obj)
>>{
>>        fZ = obj.GetZ();
>>        fA = obj.GetA();
>>        fNb_Objects++;
>>        AddToObjList(this);
>>}
>>
>>MyNuc::~MyNuc()
>>{
>>        fNb_Objects--;
>>        if(!fNb_Objects) delete fObjList;
>>}
>>
>>Int_t MyNuc::GetZ() const
>>{
>>        return (Int_t)fZ;
>>}
>>
>>Int_t MyNuc::GetA() const
>>{
>>        return (Int_t)fA;
>>}
>>
>>Int_t MyNuc::GetNbObj(Option_t *opt)
>>{
>>        if(strcmp(opt,"")) cout << "fNb_Objects=" << fNb_Objects << ", size of list=" << fObjList->GetSize() << endl;
>>        return fNb_Objects;
>>}
>>
>>void MyNuc::Clear(const Option_t *opt)
>>{
>>        TLorentzVector::Clear(opt);
>>        fZ=fA=0;
>>}
>>
>>void MyNuc::SetPxPyPz(Float_t px, Float_t py, Float_t pz)
>>{
>>        Float_t mass = 931.5*GetA();
>>        TLorentzVector::SetXYZM(px,py,pz,mass);
>>}
>>
>>    -----------------------------------------------------------------------
>>#include "MyNuc.h"
>>#include "TClonesArray.h"
>>
>>void test()
>>{
>>        MyNuc a;
>>        a.GetNbObj("print");
>>
>>        TClonesArray tca("MyNuc", 50);
>>
>>        tca.ExpandCreate(5);
>>        a.GetNbObj("print");
>>        tca.Clear("C");
>>
>>        tca.ExpandCreate(3);
>>        a.GetNbObj("print");
>>        tca.Clear("C");
>>
>>        tca.ExpandCreate(5);
>>        a.GetNbObj("print");
>>        tca.Clear("C");
>>}
>>    
>>


-- 

ganil logo <http://www.ganil.fr>
John D. Frankland <mailto:frankland@ganil.fr>
Beam Coordinator
GANIL
B.P. 55027
14076 CAEN Cedex 05

*tel:* +33 (0)231454628
*fax:* +33 (0)231454665



This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:13 MET