TTree and STL vector

Hi,

I try to get TTree* working with STL vector in CINT. Here is the relevant part of my code (ROOT 5.10-00):

std::vector fTrees;
fTrees.push_back( (TTree*) fFile->Get(“MuPlus”) ); // fFile is of type TFile*
fTrees.push_back( (TTree*) fFile->Get(“MuMinus”) ); // MuPlus and MuMinus
// are valid tree names
int curEvtID;
for ( std::vector::iterator treeItr = fTrees.begin();
treeItr != fTrees.end(); treeItr++ ) {
treeItr->SetBranchAddress(“EventID”, &curEvtID);
}

CINT stops at treeItr->SetBranchAddress(“EventID”, &curEvtID) with the error: “non class,struct,union object treeItr used with . or ->”.

Using either “(*treeIt)->” or “&(*treeItr)->” leads to a segmentation fault.

Anybody any idea what’s wrong here?

Cheers, Alexander

You have an error in the definition of your std::vector. Instead of

it should be

Rene

Dummy

Sorry, this is a typo in the posted text. I do have

in my code. Also the correct loop line in my code reads

Alexander

[quote]CINT stops at treeItr->SetBranchAddress(“EventID”, &curEvtID) with the error: “non class,struct,union object treeItr used with . or ->”. [/quote]This actually accurate since the type of ‘treeItr->’ is TTree* and hence you still need to dereference it.

In simple tries I got:

root [8] (*treeItr)->GetName() (const char* 0x14048f8)"T1"

Now the possible problem is that the file has been closed (and hence the TTree object has been deleted and hence the pointers are invalid).

Cheers,
Philippe

Hi Philippe,
thanks for the help but I don’t think it is the status of the file. I just tried the following

TTree* tree;
...
cout << tree->GetName() << endl;
std::vector<TTree*> fTrees;
fTrees.push_back(tree);
for ( std::vector<TTree*>::iterator treeItr = fTrees.begin(); 
       treeItr != fTrees.end(); treeItr++ ) {
  cout << (*treeItr)->GetName() << endl;
} 

The first ‘cout’ line gives the correct answer where for the second I get a segmentation fault. So it cannot be the status of the file.

Actually, the whole thing works when I type it on the root command line. In my program fTrees is defined as a private variable in a class. The push_back is done in a method of this class. Could the class structure be the reason for the segmentation fault?

Cheers, Alexander

Hi Alexander,

[quote] Could the class structure be the reason for the segmentation fault? [/quote]It is hard to tell. I recommend that you send me a complete running example so that I can reproduce your observations.

Cheers,
Philippe

Hi Philippe,

I attached a compressed version of my program which shows the same “features” as the full version.

In the current form the program crashes at the ‘cout’ with a segmentation fault. However, after commenting out the ‘while’ loop in ‘Simulation::Process’ the program runs without a problem. Also, compiling the original version (including the ‘while’ loop) with .L test.C+ and running test() afterwards is ok.

I can’t imagine that the ‘while’ loop itself is the problem. But I don’t know what could be the real cause for the segmentation violation.

As a note: Actually, I would prefer to compile the program but the classes that I have to use need the ‘shared_ptr’ from the ‘boost’ package. Up to now I haven’t managed to integrate them in the correct way. Compiling the program in root yields a lot of error messages of the form

Error: no such template shared_ptr<...> FILENAME:LINENUMBER:

Any idea here would also be welcome.

Cheers, Alexander
test.C (1.02 KB)

Unfortunately this is known problem of the CINT byte-code optimizer.

You have several work-arounds:
[ul]Disable the CINT optimizer by issuing the CINT command .O 0
Generate a dictionary for vector<TTree*> (see below)
Compile your code (use ACLiC for examepl)[/ul]

[quote] that I have to use need the ‘shared_ptr’ from the ‘boost’ package.
[/quote]

You need to hide all boost header file from CINT:#ifndef __CINT__ #include <boost/shared_ptr.h> #endif

You also may need to hide data member and function using it.

Cheers,
Philippe.

To generate a dictionary for vector<TTree*>, you simple need a file containing:#include <vector> class TTree; #ifdef __MAKECINT__ #pragma link C++ class vector<TTree*>; #pragma link C++ class vector<TTree*>::iterator; #pragma link C++ function operator==(const vector<TTree*>::iterator&,const vector<TTree*>::iterator&); #endif
and load it via ACLiC.

[quote]To generate a dictionary for vector<TTree*>, you simple need a file containing:#include <vector> class TTree; #ifdef __MAKECINT__ #pragma link C++ class vector<TTree*>; #pragma link C++ class vector<TTree*>::iterator; #pragma link C++ function operator==(const vector<TTree*>::iterator&,const vector<TTree*>::iterator&); #endif
and load it via ACLiC.[/quote]

Great, it works now! Thanks a lot, Philippe!

I also will try to compile the program. You write

[quote] You need to hide all boost header file from CINT:

#ifndef __CINT__
#include <boost/shared_ptr.h>
#endif

You also may need to hide data member and function using it.[/quote]
I’m not familiar with the way programs are compiled with ACLiC so what exactly is happening? From what you write I understand that CINT is called first (what is it doing?) and has trouble with the shared_ptr. What happens afterwards?

Cheers, Alexander

You can find the details about ACLiC in the User’s Guide :slight_smile:
In short ACLiC does
[ul] - run rootcint (and hence CINT) on your script to generate the dictionary for the symbol declared in your scripts (and its header file)

  • run the compiler to generate a shared library containing your script and its dictionary
  • load the resulting shared library.[/ul]

Cheers,
Philippe.