Error reading Int_t array branch data from MARLEY output

Hello,
I’ve run into a strange error when trying to open data from the flat root output file that MARLEY generates. When I run

TFile *file = new TFile("out.root");
TTree *tree = (TTree*)file->Get("mst");

Int_t* pdgp = nullptr; // Pointer to the array of PDG codes
Int_t np = 0; // Number of PDG codes in pdgp for each entry

tree->SetBranchAddress("np", &np);
tree->SetBranchAddress("pdgp", &pdgp);
  
std::cout << "Before GetEntry, np: " << np << ", pdgp pointer is null? " << (pdgp==nullptr) << std::endl;

tree->GetEntry(0);
  
std::cout << "The pointer to pdgp is: " << pdgp << "\n";
std::cout << "After GetEntry, np: " << np << ", pdgp pointer is null? " << (pdgp==nullptr) << std::endl;

My output looks like this:

root [0] TFile *file = new TFile("out.root");
root [1] TTree *tree = (TTree*)file->Get("mst");
root [2] Int_t* pdgp = nullptr; // Pointer to the array of PDG codes
root [3] Int_t np = 0; // Number of PDG codes in pdgp for each entry
root [4] 
root [4] tree->SetBranchAddress("np", &np);
root [5] tree->SetBranchAddress("pdgp", &pdgp);
root [6] std::cout << "Before GetEntry, np: " << np << ", pdgp pointer is null? " << (pdgp==nullptr) << std::endl;
Before GetEntry, np: 0, pdgp pointer is null? 1
root [7] tree->GetEntry(0);
root [8] std::cout << "The pointer to pdgp is: " << pdgp << "\n";
The pointer to pdgp is: 0x1600000016
root [9] std::cout << "After GetEntry, np: " << np << ", pdgp pointer is null? " << (pdgp==nullptr) << std::endl;
After GetEntry, np: 4, pdgp pointer is null? 0

If I check what ROOT says in terminal about pdgp, I get this:

root [10] pdgp
(Int_t *) 0x1600000016 <invalid memory address>

If I print the TTree, I get an output like this for those two baskets:

*............................................................................*
*Br   23 :np        : np/I                                                   *
*Entries :        5 : Total  Size=        561 bytes  File Size  =         88 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=   1.00     *
*............................................................................*
*Br   24 :pdgp      : pdgp[np]/I                                             *
*Entries :        5 : Total  Size=        731 bytes  File Size  =        110 *
*Baskets :        1 : Basket Size=      32000 bytes  Compression=   1.62     *
*............................................................................*

Which looks exactly like what I think I should expect a dynamically sized basket of integers to look like.

When I go to try and use the integer at this “invalid memory address”, I get a crash:

root [11] pdgp[0]

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007f89e0d182ca in wait4 () from /usr/lib64/libc.so.6
#1  0x00007f89e0c61953 in do_system () from /usr/lib64/libc.so.6
#2  0x00007f89e1706d74 in TUnixSystem::StackTrace() () from /usr/lib64/root/libCore.so.6.30
#3  0x00007f89e1703c95 in TUnixSystem::DispatchSignals(ESignals) () from /usr/lib64/root/libCore.so.6.30
#4  <signal handler called>
#5  0x00007f89e0759025 in ?? ()
#6  0x00007ffd5e3f7d10 in ?? ()
#7  0x00007f89dc198215 in cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const () from /usr/lib64/root/libCling.so
#8  0x00007f89dc12e971 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /usr/lib64/root/libCling.so
#9  0x00007f89dc1309b2 in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /usr/lib64/root/libCling.so
#10 0x00007f89dc130c8b in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) () from /usr/lib64/root/libCling.so
#11 0x00007f89dc1f0c3f in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /usr/lib64/root/libCling.so
#12 0x00007f89dc04a35c in HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /usr/lib64/root/libCling.so
#13 0x00007f89dc059003 in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /usr/lib64/root/libCling.so
#14 0x00007f89e1a77f1b in TRint::ProcessLineNr(char const*, char const*, int*) () from /usr/lib64/root/libRint.so.6.30
#15 0x00007f89e1a7833c in TRint::HandleTermInput() () from /usr/lib64/root/libRint.so.6.30
#16 0x00007f89e1702c7c in TUnixSystem::CheckDescriptors() () from /usr/lib64/root/libCore.so.6.30
#17 0x00007f89e17049a8 in TUnixSystem::DispatchOneEvent(bool) () from /usr/lib64/root/libCore.so.6.30
#18 0x00007f89e161f9f1 in TSystem::Run() () from /usr/lib64/root/libCore.so.6.30
#19 0x00007f89e15a4227 in TApplication::Run(bool) () from /usr/lib64/root/libCore.so.6.30
#20 0x00007f89e1a79c18 in TRint::Run(bool) () from /usr/lib64/root/libRint.so.6.30
#21 0x000055e5bea32303 in main ()
===========================================================


The lines below might hint at the cause of the crash. If you see question
marks as part of the stack trace, try to recompile with debugging information
enabled and export CLING_DEBUG=1 environment variable before running.
You may get help by asking at the ROOT forum https://root.cern/forum
preferably using the command (.forum bug) in the ROOT prompt.
Only if you are really convinced it is a bug in ROOT then please submit a
report at https://root.cern/bugs or (preferably) using the command (.gh bug) in
the ROOT prompt. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007f89e0759025 in ?? ()
#6  0x00007ffd5e3f7d10 in ?? ()
#7  0x00007f89dc198215 in cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const () from /usr/lib64/root/libCling.so
#8  0x00007f89dc12e971 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) () from /usr/lib64/root/libCling.so
#9  0x00007f89dc1309b2 in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /usr/lib64/root/libCling.so
#10 0x00007f89dc130c8b in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) () from /usr/lib64/root/libCling.so
#11 0x00007f89dc1f0c3f in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /usr/lib64/root/libCling.so
#12 0x00007f89dc04a35c in HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) () from /usr/lib64/root/libCling.so
===========================================================

Can someone help me make sense of this? I found a similar post from a year ago which is using the same sort of files output from MARLEY, but in PyROOT.

Attached below are a very small ROOT file and the macro I’ve been using to try and analyze the ROOT file.

out.root (10.5 KB)
minimal.C (6.7 KB)


ROOT Version: 6.30/04
Platform: Almalinux 9.3
Compiler: g++ 11.4.1


You need to allocate the array and pass its starting address:

Int_t* pdgp = new Int_t[max_number_elements]; // Pointer to the array of PDG codes
...
tree->SetBranchAddress("pdgp", &(pdgp[0]));
....