Just adding a custom class (with a TClonesArray) to ROOT here and finding that if it is empty (no entries added) at the time the class gets Fill()-ed into the output tree, I get a seg fault here (gdb output):
#0 MyClass_IsA (obj=0x841) at MyClassDict.cxx:157
#1 0x401b32f4 in TClass::GetActualClass(void const*) const () from /cern/root/lib/libCore.so
#2 0x401165ea in TBuffer::WriteObjectAny(void const*, TClass const*) () from /cern/root/lib/libCore.so
#3 0x40116001 in TBuffer::WriteFastArray(void**, TClass const*, int, bool, TMemberStreamer*) () from /cern/root/lib/libCore.so
Googling on “empty TClonesArray” comes up with 1 (unanswered) question the same as this one, and no useful info… therefore I conclude I am doing something stupid. I believe I have followed the Event example.
Sound familiar to anyone?
From the limited information your provided (stack trace not long enough, no info on what your code really does), I guess that you have not properly set the pointer you passed to the Branch method you called on your TTree. Specifically:
[quote]#0 MyClass_IsA (obj=0x841) at MyClassDict.cxx:157
[/quote]tells me that the TTree is trying to save an object for which it has a received a MyClass* and that he thinks the object is at the address 0x841.
Actually most likely you wrote:
MyClass *p = ...;
MyClass *p = ...;
Note that Branch needs the address of the pointer.
Thanks for the reply. The pointer seems set properly - I think the problem is isolated to whether or not the TClonesArray is empty or not. The code is set up similar to Event in that there is the main class which has a TClonesArray. The TCA is normally filled with MyClasses and then Filled in the tree. When the number of MyClasses added to the TCA is >0, then all works well. When the TCA is empty and I try to fill I get a seg fault. It seems like the TTree is trying to get info on a MyClass when there isn’t one in the TCA, but if this is expected behavior it seems like a big limitation.
I’ll try to work up some simplified example code.
Below is a longer stack trace.
#0 0x416874cc in MyClass_IsA (obj=0x8c9000f) at MyClassDict.cxx:157
#1 0x401b4dea in TClass::GetActualClass(void const*) const () from /cern/root/lib/libCore.so
#2 0x401172ae in TBuffer::WriteObjectAny(void const*, TClass const*) () from /cern/root/lib/libCore.so
#3 0x40116cc5 in TBuffer::WriteFastArray(void**, TClass const*, int, bool, TMemberStreamer*) () from /cern/root/lib/libCore.so
#4 0x4020498e in int TStreamerInfo::WriteBufferAux<char**>(TBuffer&, char** const&, int, int, int, int) ()
#5 0x40e923b6 in TBranchElement::FillLeaves(TBuffer&) () from /cern/root/lib/libTree.so
#6 0x40e89689 in TBranch::Fill() () from /cern/root/lib/libTree.so
#7 0x40e91e32 in TBranchElement::Fill() () from /cern/root/lib/libTree.so
#8 0x40e91e13 in TBranchElement::Fill() () from /cern/root/lib/libTree.so
#9 0x40eb57b6 in TTree::Fill() () from /cern/root/lib/libTree.so
#10 0x0804ef5d in main (argc=3, argv=0xbfffe3a4) at main.cpp:169
#11 0x417ac7f7 in __libc_start_main () from /lib/i686/libc.so.6
Humm … it kinda interesting that the value pass to MyClass_IsA is different in your second trace (It feels like an uninitialized memory read).
I would need to actually see the code setting up your tree. I just tried to set the number of Track to zero in Event.cxx and see no problem.
the stack trace only makes sense if there was something in the TCA - otherwise writing the streamer info would have been enough, the objects (which objects would not have been streamed, just as ruutuser pointed out. So my guess is that the TCA is not properly cleared from the previous event (which would also explain why it happens for empty TCAs, but not for, errr, “full” TCAs, i.e. if this event’s TCA’s size is >= last event’s). Can we see the fill / event loop, too, please? O, and what root version are we talking about?