Segmentation Violation in TTree::GetEntry()

Hi,

I’m fairly new to root. I’m using Version 4.04/02b 3 June 2005 on Linux and my program is a standalone.

I’ve created a tree using a Class I defined. While trying to get the entries of the tree I’m able to do so for the first two entries. On the third, the GetEntry prints the following warning and then crashes:

Error in TExMap::Remove: key 65536 not found at 147
Warning in TBuffer::CheckObject: reference to object of unavailable class TClonesArray, offset=65536 pointer will be 0
Error in TExMap::Remove: key 768 not found at 266
Warning in TBuffer::CheckObject: reference to object of unavailable class TClonesArray, offset=768 pointer will be 0
Error in TBuffer::ReadObject: Got object of wrong class (Got RawTrack while expecting TClonesArray)
Error in TExMap::Remove: key 50331648 not found at 463
Warning in TBuffer::CheckObject: reference to object of unavailable class TClonesArray, offset=50331648 pointer will be 0
Error in TBuffer::ReadObject: Got object of wrong class (Got RawTrack while expecting TClonesArray)

I’m unable to understand what’s going on. I would really appreaciate your help with this issue.

Thanks,

Pedro M Duarte

Following is the code for my program:

//create ROOT tree
TTree *raw = new TTree(“Raw”,“Raw Data Tree”);
RawTrack *rtrack = new RawTrack();
raw->Branch(“RawTrackBranch”,“RawTrack”,&rtrack,32000,99);

//fill the tree

//read the tree to fill histograms
Int_t n = raw->GetEntries(); <----------------- It crashes here.----------
for( Int_t i=0; i!=n; i++) {
raw->GetEntry(i);
for( Int_t de=0; de!=p->fMax; de++){
if( rtrack->fHits[de] ) {
TClonesArray &hits = *( rtrack->fHits[de] );
for (Int_t hit=0; hit!=rtrack->fNHits[de]; hit++){
RawHit h = ((RawHit)hits[hit]) ;
hM[de][h->fNPlane][h->fWire]->Fill( h->fData );
}
}
}
rtrack->Clear();
}

//________________________________________________________________
class RawHit : public TObject {

private:
Bool_t fIsValid;

public:
char fPlane; // plane name
Int_t fNPlane; // plane number
Int_t fWire; // wire number
Int_t fData; // time

RawHit();
~RawHit();
RawHit(Int_t t, Int_t c, Int_t d, PWCSetup *p);
void Print() const;

ClassDef(RawHit,1) //Raw mwpc hit
};

//________________________________________________________________
class RawTrack : public TObject {

private:
Bool_t fIsValid; //

public:
Int_t fMax; //number of devices
TClonesArray *fHits[10]; //an array of hits per device
Int_t fNHits[10]; //hits per device

RawTrack();
~RawTrack();
void Clear();
void AddHit(Int_t t, Int_t c, Int_t d, PWCSetup *p);
Int_t GetNHits(Int_t i) {return fNHits[i];};
void Print() const;

ClassDef(RawTrack,1) //Raw track for an event
};

//________________________________________________________________
RawHit::RawHit() : fIsValid(kFALSE)
{
// Create a RawHit object.
}

//________________________________________________________________
RawHit::~RawHit()
{
// Destructs a RawHit object.
}

//________________________________________________________________
RawHit::RawHit(Int_t t, Int_t c, Int_t d, PWCSetup *p)
{
// Create a RawHit object.
fIsValid = kTRUE;
fPlane = p->Setup[t][c]->fPlane;
fNPlane = p->Setup[t][c]->fNPlane;
fWire = p->Setup[t][c]->fWireN;
fData = d;
}

//________________________________________________________________
void RawHit::Print() const
{
if (fIsValid){
std::cout << “plane:” << fPlane << " planeNum:" << fNPlane << " wire:" << fWire << " data:" << fData << std::endl;
}
else {
std::cout << “Initialize the object before printing!” << std::endl;
}
}

//________________________________________________________________
RawTrack::RawTrack()
{
// Create a RawTrack object.
fMax = NDEVICES;
for(Int_t i=0; i!=fMax; i++){
fHits[i] = 0; //default initialization of pointer
fNHits[i]=0;
}
fIsValid = kTRUE;
}

//________________________________________________________________
RawTrack::~RawTrack()
{
// Destruct a RawTrack object.
Clear();
}

//________________________________________________________________
void RawTrack::Clear()
{
for(Int_t i=0; i!=fMax; i++) {
if (fHits[i]) {
fHits[i]->Delete();
fHits[i]=0; //default initialization of pointer
}
fNHits[i]=0;
}
}

//________________________________________________________________
void RawTrack::AddHit(Int_t t, Int_t c, Int_t d, PWCSetup *p)
{
Int_t station = p->Setup[t][c]->fStation;
if ( d>TDCLOWCUT && d<TDCHIGHCUT ){
if (station < fMax ){
if (!fHits[station]) fHits[station] = new TClonesArray(“RawHit”,200);
TClonesArray &hits = *fHits[station];
new(hits[fNHits[station]]) RawHit(t,c,d,p);
fNHits[station]++;
}
}
else{
std::cout << “Time out of cuts:: Station :” << station << " Time : " << d << std::endl;
}
}

//________________________________________________________________
void RawTrack::Print() const
{
if (fIsValid){
std::cout << “Mwpc Hits” << std::endl;
for(Int_t j=0; j!=fMax; j++){
std::cout << “Station " << j+1 << std::endl;
if ( fHits[j] ){
TClonesArray &hits = fHits[j];
for(Int_t i=0; i<fNHits[j]; i++)
((RawHit
)hits[i])->Print();
if( fNHits ==0 )
std::cout << " -empty-” << std::endl;
}
else {
std::cout << " -empty-" << std::endl;
}
}
}
else {
std::cout << “Initialize the object before printing!” << std::endl;
}
}

Could you move to a more recent version (eg 5.14 or 5.15/02) and let us know
if you still observe the problem ?

Rene

I got this sorted out by avoiding the use of an array of TClonesArray pointers in my class definition.

Pedro.

I am observing the same problem in Version 5.14/00e. When I set the branch address to be the object of my event class and then do GetEntry(x) (with whatever x exists in the object) I get a segmentation violation.

Has this problem been observed in more cases and solved without having to “work around” in the event class?

Cheers,
Staffan

Hi,

The original problem was most likely due to the use of TClonesArray *arr[10]; which is not fully supported.

In your case, the segmentation fault could have many causes (the simplies might that you did not set the address correctly and/or did not initialize the pointer properly). We would need more details (at the very least code snippet and better yet a full example) to be able to stir you in the right direction.

Cheers,
Philippe

OK, here is the code for what I’m doing. The file test3.root contains a Tree DF which contains an object of type L2SV with name L2SV_1. I can do for instance br1->GetEntries() and get the correct number of entries, but when I do br1->GetEntry(x) I get a segmentation violation. When I define the branch as one of the variables of the L2SV class things work fine, for instance if I instead do TBranch *br1 = t1->GetBranch(“IntervalEventRate”); . But this is not what I want as I can have more objects within the tree which have the same variables.

gSystem->Load("/afs/cern.ch/user/r/rabello/public/running/head/pyis/head/python/root/i686-slc4-gcc34-opt/L2SV.so");
TFile *f = new TFile(“test3.root”);
L2SV *l2sv = new L2SV();
TTree *t1 = (TTree *) f->Get(“DF”);
TBranch *br1 = t1->GetBranch(“L2SV_1”);
br1->SetAddress(l2sv);
br1->GetEntry(1); <— Here is where the segmentation violation occurs.

//-------------
#ifndef L2SV_ROOT_H
#define L2SV_ROOT_H
#include “TObject.h”
#include “TClonesArray.h”
#include

class L2SV: public TObject {
public:
Double_t IntervalEventRate; //Interval Throughput (Hz)
Int_t errors; //Number of errors
Int_t ForcedAccepts; //Number of forced accepts
Int_t LVL1_events; //Number of LVL1 events
Double_t IntervalTime; //Interval length(s)
Int_t RejectedEvents; //Number of rejected events
std::string Identity; //Identity of this node
Int_t LVL2_events; //Number of LVL2 events
Float_t time; //Time of the object’s last modification
Double_t AvgEventRate; //Average Throughput (Hz)
Int_t AcceptedEvents; //Number of accepted events
L2SV();
virtual ~L2SV();
ClassDef(L2SV,1)
};

#endif //L2SV_ROOT_H

Cheers,
Staffan

I found the error myself. And yes, obviously it was an error with the address. I feel a bit stupid for not finding it before.

Sorry for taking up your time, and cheers,
Staffan

Note that in newer version of ROOT (5.12 and above) and if you use TTree::SetBranchAddress rather than TBranch::SetAddress, you would have gotten an error message telling you of the mismatch.

Cheers,
Philippe

Thank you, I will remember to use this in the future!

/S