Hi Franck,
thanks for our help.
Concerning the Clear()/Delete() for TRefArray, I just followed
the Event class provided in the ROOT test/ directory.
I didn't know about the TRefArray's address having to be set, this
should appear in the doc.
And concerning the unique id, the problem is that
once set in a ROOT session , one cannot re-reference an object
without affecting this unique id ; this comes from :
UInt_t TProcessID::AssignID(TObject *obj)
{
UInt_t uid = obj->GetUniqueID() & 0xffffff;
if (obj == fgPID->GetObjectWithID(uid)) return uid;
if (obj->TestBit(kIsReferenced)) {
fgPID->PutObjectWithID(obj,uid);
return uid;
}
fgNumber++;
obj->SetBit(kIsReferenced);
uid = fgNumber;
obj->SetUniqueID(uid);
fgPID->PutObjectWithID(obj,uid);
return uid;
}
So in the code I gave :
the first if is false, than TestBit is true for
the object which have been referenced when creating the
ROOT file and PutObjEctWithID is called and looks like :
void TProcessID::PutObjectWithID(TObject *obj, UInt_t uid)
{
//stores the object at the uid th slot in the table of objects
//The object uniqueid is set as well as its kMustCleanup bit
//if (!fObjects) fObjects = new TObjArray(100);
if (uid == 0) uid = obj->GetUniqueID() & 0xffffff;
fObjects->AddAtAndExpand(obj,uid);
obj->SetBit(kMustCleanup);
}
Here you can see that the uid is used as a index number (fObjects
is a TObjArray) and there is no check if this index exists
already, the array is expanded and I suspect that the copy
of a already existing object is done here, that's why I
have 2 times the same objects in the final output and loose
the other one.
But here I would need the help of some expert.
To remain the goal I want to reach :
1) In a ROOT session build objects and keep reference
from some of them to other ones.
2) In another session play with the referenced objects
and have the possibility to refer them also to new
created objects and save everything .
thanks for the help,
seb.
On Thu, 30 Oct 2003, Frankland John wrote:
> Hi Sebastien
>
> I tried your code and changed a few things :
>
> //________________________________________
> MyClassRef::~MyClassRef()
> {
> fRefArray.Clear();---> you don't really want to delete the objects you
> reference, do you ?
> }
>
> void MyClassRef::Clear()
> {
> fRefArray.Clear();---> just clear out the list of references, but the
> objects are deleted by the TClonesArray
> }
> //_________________________________________
> void ReadTree()
> {
> .....
> TClonesArray* clones = 0;
>
> tree->SetBranchAddress("b_clones",&clones);
>
> //connect the TRefArray branch as well - I have recently discovered that
> if a branch contains objects
> //which reference other objects in unconnected branches, the TTree can
> create those objects all by
> //itself (as well as recreating the TClonesArray without deleting the
> old one) and cause monumental
> //memory leaks...
> MyClassRef* myclassref1 = 0;
>
> tree->SetBranchAddress("b_myclassref1",&myclassref1);
> //_______________________________________________
>
> but I still see the same result as you -
> twice as many objects in the final myclassref2 and I don't know why. As
> for the
> result being different when you read or write, if you mean the unique
> identifiers
> are not the same, I don't think it's important as they are just internal
> counters
> for ROOT (aren't they ???).
>
> Sorry
> John
>
> > The final output has changed.
> >
> > Well, this is due to the fact that it is a new ROOT
> > session.
> >
> > But what I'd like to understand is why the objects
> > in myclassref2's TRefArray have been doubled ?
> >
> >
> >
>
>
> --
>
> 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:16 MET