Confused about TBranch::SetAddress

I’m trying to get a Root Macro to read objects from a file using TBranch::SetAddress. I was getting a segmentation fault so I’m obviously doing something wrong with pointers. I was looking at old posts and I can’t reconcile the following two posts that I found on root support - what am I missing here?
I’d like to understand what exactly a TBranch is and what TBranch::SetAddress really does so that I can use them properly. Please can anyone clarify or otherwise point me to a definitive post or some example that explains this more clearly. I’m reading Chapter 12 of the users guide, but in any case, I still can’t quite understand the differences between the posts below.

Cheers

Ben

========================================================================================

Re: [ROOT] TBranch::SetAddress() problems
From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Sep 20 2002 - 22:10:49 MEST

Hi Ole,

TTree::GetEntry (or TBranch::GetEntry) read at the place
indicated by the previous TBranch::SetAddress. It cannot read
and store at multiple addresses. You must call
GetEntry for each address.
Also, in read mode, never do
MyEvent* e1 = new MyEvent();
b->SetAddress(&e1);

but
MyEvent* e1 = 0;
b->SetAddress(&e1);

otherwise, you run the risk of memory leaks.
In your case, do:

TBranch* b = Physics->GetBranch(“Event”);

----- at one place ------
MyEvent* e1 = 0;
b->SetAddress(&e1);
b->GetEntry(i);

— at another place ----
MyEvent* e2 = 0;
b->SetAddress(&e2);
b->GetEntry(i);

Rene Brun

=============================================================================================================

Error Reading Tree branch in QT
PostPosted: Fri Oct 07, 2005 21:24

char* n ="";
bb->SetAddress(n);
is incorrect! You are requesting ROOT to write into a const zero length array!. The fact that it does crash in CINT is simply part of the fact that the expected behavior in this case is random.
Instead you should use
Code:
char* n = new char[max_len];
bb->SetAddress(n);

Cheers,
Philippe.

Please re-read the User’s Guide chapter on TTree, this should be explained there. In addition, look at the example in tree[1234].C in tutorials.

The 2 post that you are quoting need to be read in their context. The behavior of SetBranchAddress is highly depend on the ‘nature’ of the branch and whether you set it in emulation (SetMakeClass(1)) or object mode (the default).

Lastly, please provide a running example where we can pin-point more accurately the mis-understanding in your context.

Cheers,
Philippe

It looks like you have a problem with C++ (or C) to understand the difference
between the value of a pointer and the address of the pointer, in particular
when the pointer points to an array. In case of an array like with
char* n = new char[max_len];
calling
bb->SetAddress(n);
is identical to
bb->SetAddress(&n[0]);
so my post and Philippe’s post were identical.

Rene

The context is a g++ compiled CMSSW analysis program

The following extract segfaults:

reco::PhotonCollection* photons = 0;
events->SetBranchAddress(“recoPhotons_photons__smWgPythia.obj”,&photons);
events->GetEntry(entry);

This does not segfault:

reco::PhotonCollection* photons = new reco::PhotonCollection();
events->SetBranchAddress(“recoPhotons_photons__smWgPythia.obj”,&photons);
events->GetEntry(entry);

But I thought the pointer to the object you are filling could be initialized to 0. The users guide suggests this: “event [in my case ‘photons’] must be null or point to a valid object;” And this is suggested by Rene’s old post. I think this is the source of my confusion. It occurs to me this might be because I am not using CINT - a compiled c++ program would not allow the TTree/TBranch to create a fresh reco::PhotonCollection itself since it has no dictionary?
I’m just trying to find out enough so that I can be confident I don’t have a memory problem 100000 events later.

Thanks for your help.

Ben

[quote]The users guide suggests this: “event [in my case ‘photons’] must be null or point to a valid object;” And this is suggested by Rene’s old post.[/quote]This is true for the top level objects. In your case you setting somewhere in the middle of the hierachy. In this case (at least for now) you might need to pass something that points to a valid object.

[quote]since it has no dictionary? [/quote]Especially If you use compiled code, you must have a dictionary otherwise your object and TTree’s view of it will be different resulting in your object being imporperly filled!

Philippe