_ROOT Version: 6.13
_Platform: Ubuntu 16.04
_Compiler: gcc 5.4.0
I have a base class defined roughly as so
class myClass {
public:
myClass(const char* filename, const char* treename){
f = new TFile(filename, "read");
T = (TTree*)f->Get(treename);
}
doSomething(){
for(int i=0; i<T->GetEntriesFast(); i++){
T->GetEvent(i);
// some code
}
}
TFile* f;
TTree* T;
}
When I try to call doSomething() I get a segmentation violation
Try with:
class myClass {
public:
myClass(const char *filename, const char *treename) {
f = T = 0;
if (!(filename && filename[0])) return; // just a precaution
if (!(treename && treename[0])) return; // just a precaution
f = TFile:Open(filename);
if ((!f) || f->IsZombie()) { delete f; f = 0; return; } // file error
f->GetObject(treename, T);
if (!T) { delete f; f = 0; return; } // no tree
}
~myClass() {
delete f; // automatically deletes "T", too
// f = T = 0;
}
doSomething() {
if (!T) return; // just a precaution
for(Long64_t i = 0; i < T->GetEntries(); i++) {
if (T->GetEntry(i) < 1) break; // no entry
// some code
}
}
TFile *f;
TTree *T;
};
Unfortunately that didn’t work. I should apologize though, in an effort to keep the code as simple as possible I didn’t fully explain my problem. I’ve actually fixed the problem, but I’m not satisfied with the fix. Below is an outline of what I did
class myClass {
public:
myClass(const char* filename_1, const char* filename_2, const char* treename_1, const char* treename_2){
f1 = new TFile(filename_1, "read");
f2 = new TFile(filename_2, "read");
T1 = (TTree*)f1->Get(treename_1);
T2 = (TTree*)f2->Get(treename_2);
}
void AnalyzeData(){
int nEvts = T1->GetEntriesFast();
for(int i=0; i<nEvts; i++) processEvent(i);
}
virtual void processEvent(int i){ return -1; }
TFile* f1;
TFile* f2;
TTree* T1;
TTree* T2;
};
class mySubclass : public myClass {
public:
mySubclass(const char* filename_1, const char* filename_2) : myClass(filename_1,filename_2, "tree1", "tree2"){
/* Uncommenting will cause a crash
Object1* pO1 = &O1;
Object2* pO2 = &O2;
T1->SetBranchAddress("O1", &pO1);
T2->SetBranchAddress("O2", &pO2);
*/
}
void processEvent(int i){
/////////////////////////////////////////
// putting it here does not cause a crash
Object1* pO1 = &O1;
Object2* pO2 = &O2;
T1->SetBranchAddress("O1", &pO1);
T2->SetBranchAddress("O2", &pO2);
/////////////////////////////////////////
T1->GetEvent(i);
int nEvts = T2->GetEntriesFast();
for(int e=0; e<nEvts; e++){
T2->GetEvent(e); // crashes here
// some code
}
}
Object1 O1;
Object2 O2;
};
I want to set the branches of the trees in the constructor of the subclass instead of in processEvent, but that causes a segmentation violation.
As an aside, no matter where I put the code in the constructor of the subclass (i.e. with and without a crash), calling T1->Print() or T2->Print() in processEvent prints out the trees correctly.
Try with:
class mySubclass : public myClass {
public:
mySubclass(const char *filename_1, const char *filename_2)
: myClass(filename_1, filename_2, "tree1", "tree2") {
p01 = p02 = 0;
if (T1) T1->SetBranchAddress("O1", &pO1);
if (T2) T2->SetBranchAddress("O2", &pO2);
}
~mySubclass() {
if (T1) { T1->ResetBranchAddresses(); delete p01; }
if (T2) { T2->ResetBranchAddresses(); delete p02; }
// p01 = p02 = 0;
}
void processEvent(Long64_t i) {
if (!(T1 && T2)) return; // just a precaution
if ((T1->GetEntry(i) < 1) || (!p01)) return; // "entry" problem
Long64_t nEvts = T2->GetEntries();
for(Long64_t e = 0; e < nEvts; e++) {
if ((T2->GetEntry(e) < 1) || (!p02)) break; // "entry" problem
// some code
}
}
Object1 *pO1;
Object2 *pO2;
};