TTree with std::vector<std::vector<T> >

Dear Rooters,

I have some problems with Roottrees and how to get them work. Please find an example Visual C++ 7.1 Project attached to this post.
Here I am trying to fill the tree with a std::vector of a std::vector. In this example this is

typedef std::vector<MyDetektorHit> dhVec typedef std::vector<dhVec> MyEreignis
where I am trying to fill the tree with the MyEreignis vector. Obviously I’m doing something wrong, because everytime I’m running this programm it crashes. But if I comment out the line

t->Fill()

in MyAnalyze.cpp, then the program runs fine without crashing, but of curse also without filling the tree. Is the way that I call TTree::Branch wrong? I am building dictionaries for both classes that are part of the vectors.

Please take this Project only as a small example reproducing my Problem. In the real Program, where I have lots of MyPeak Instances, I’m not filling the vectors with the same MyPeak over and over again.

I am using ROOT Ver. 5.16

Thank you,

Lutz
ExampleForRootForum.zip (647 KB)

Hi,

You also need to generate the dictionary for the vector instance themself:

#pragma link C++ class std::vector<MyDetektorHit>; #pragma link C++ class std::vector<dhVec>;

Cheers,
Philippe.

Hi Philippe,

I have moved the two lines

typedef std::vector<MyDetektorHit> dhVec; typedef std::vector<dhVec> MyEreignis;
from MyAnalyze.h to the file MyDetektorHit.h and added the two lines you suggested

#pragma link C++ class std::vector<MyDetektorHit>; #pragma link C++ class std::vector<dhVec>;
to the file MyDetektorHitLinkDef.h. It compiles fine but when I run it, it crashes giving me the

following output:

[code]Please give me a proper .root Filename
test.root
Warning in TStreamerSTL::TStreamerSTL: For vector we could not find any
information about the type dhVec

==========================================
=============== STACKTRACE ===============

================ Thread 0 ================
c:\root\include\tcollectionproxyinfo.h(123): ROOT::TCollectionProxyInfo::Type<
std::vector<std::vector<MyDetektorHit,std::allocator >,std::alloc
ator<std::vector<MyDetektorHit,std::allocator > > > >::size()
libRIO!TGenCollectionStreamer::Streamer()

================ Thread 1 ================
ntdll!KiFastSystemCallRet()
kernel32!WaitForSingleObject()
libCore!`anonymous namespace’::HandleConsoleThread()
0xffffffffe87c8024 ??

================ Thread 2 ================
ntdll!KiFastSystemCallRet()
kernel32!Sleep()
libCore!TWinNTSystem::TimerThread()

================ Thread 3 ================
ntdll!KiFastSystemCallRet()
libCore!`anonymous namespace’::GetProgramCounter()
0xffffffffff006aec ??

==========================================
============= END STACKTRACE =============

[/code]

Is the reason why it crashes that the created dictionary doesn’t know what dhVec is? If so, how do I tell rootcint that dhVec is a std::vector ??

Thank you,
Lutz

[quote]Is the reason why it crashes that the created dictionary doesn’t know what dhVec is? If so, how do I tell rootcint that dhVec is a std::vector ??
[/quote]Most certainly :slight_smile:

Try:#praga link C++ typedef dhVec;

Cheers,
Philippe

Hi Philippe,

adding your suggested Line to MyDetektorHitLinkDef.h did not solve the Problem unfortunatly.
The File MyDetektorHitLinkDef.h now reads:

[code]#ifdef CINT

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;

#pragma link C++ class MyDetektorHit;
#pragma link C++ class std::vector;
#pragma link C++ typedef dhVec;
#pragma link C++ class std::vector;

#endif
[/code]
I have been playing with the position of the new line a bit, but it doesn’t matter where this line is added, the program still crahes. But this time without telling me that it doesn’t know what a dhVec is. Is this crash realated to a problem with the tree?

Here is the stacktrace of the crashed program.

[code]Please give me a proper .root Filename
test.root

==========================================
=============== STACKTRACE ===============

================ Thread 0 ================
c:\root\include\tcollectionproxyinfo.h(123): ROOT::TCollectionProxyInfo::Type<
std::vector<std::vector<MyDetektorHit,std::allocator >,std::alloc
ator<std::vector<MyDetektorHit,std::allocator > > > >::size()
libRIO!TGenCollectionStreamer::Streamer()

================ Thread 1 ================
ntdll!KiFastSystemCallRet()
kernel32!WaitForSingleObject()
libCore!`anonymous namespace’::HandleConsoleThread()
0xffffffffe87c8024 ??

================ Thread 2 ================
ntdll!KiFastSystemCallRet()
kernel32!Sleep()
libCore!TWinNTSystem::TimerThread()

================ Thread 3 ================
ntdll!KiFastSystemCallRet()
libCore!`anonymous namespace’::GetProgramCounter()
0xffffffffff006aec ??

==========================================
============= END STACKTRACE =============

[/code]

Thank you,
Lutz

Try with#pragma link C++ class MyDetektorHit+;aka requesting the new I/O for your class. If this those not solve the problem, resend me a complete example and I will look into it.

Cheers,
Philippe

Hi Philippe,

I have modified the LinkDef.h File as you suggested. But the Program still crashes.
Please find attached to this post a zip file that contains the the latest version of the VC7.1 Project.

Thank you,
Lutz
ExampleForRootForum_Mod.zip (610 KB)

Hi,

are you compiling your project in debug mode and linking against a release build of ROOT? You cannot. You must use a matching ROOT build. It’s Microsoft that screwed it up - their runtime libs are incompatible.

If this is not it then I’m sure that Philippe will find the real problem :slight_smile:

Axel.

Hi Axel,

thank you for your suggestion. Indeed I have the release build of ROOT.
But the program crashes in both scenarios: if I compile and link it in debug mode and if I compile and link it in release mode.

Thank you,
Lutz

ps: I’m rebuilding the project everytime i switch from release to debug mode.

Hi,

you are indeed linking against an incompatible runtime library. Switch from “multi-threaded” or multithreaded debug) to “multi-threaded (debug) dll” in Project / Configuration Properties / C/C++ / Code Generation.

After wards your program will still not work properly. ~MyAnalyze() fails in std::vector<std::vector<MyDetektorHit,std::allocator >,std::allocator<std::vector<MyDetektorHit,std::allocator > > >::~vector<std::vector<MyDetektorHit,std::allocator >,std::allocator<std::vector<MyDetektorHit,std::allocator > > >(). But that’s a different issue; let me know if you need help with that, too.

Axel.