ROOT Version: 6.06.08
Platform: Linux
Compiler: g++ 4.9
I seem to have a memory leak issue when reading from a TChain, which manifests only after the processing proceeds to the second file. The leak relates to a TObjArray member of the top level class being leaked (not being deleted by TBranch::SetAutoDelete). Perhaps I need to do something to update the chain variables? I’m not sure what or why though.
I have a reproducer script and a couple of sample files here: https://drive.google.com/file/d/1_hHUizuoMbH9GWmOPlseABugsJDlWKw0/view?usp=sharing
I use TChain::SetBranchAddress
either with a self-made object, or passing a pointer to a nullptr (both yield the same result), and call TBranch::SetAutoDelete
to ensure the object gets renewed with each GetEntry
call. The Event class (WCSimRootEvent) contains a TObjArray of Trigger objects (WCSimRootTrigger).
Everything appears to work fine for the first file, and after processing 500 entries in the first TFile, a gObjectTable->Print()
shows there are just 3 Events and 3 Triggers in memory (as expected; there are 3 types of event in the file).
But moving onto the second TFile, it seems subsequent GetEntry
calls do not delete the TObjArray member, and the application leaks memory. By the end of processing the second file, gObejctTable->Print()
shows just 3 Events, but some 63 Triggers, and the application memory has been climbing linearly since moving to the second file.
Am I missing something in how I process the TChain?
I’m actually a little puzzled about the process of creating an Event for the TChain ‘to use’, given that the Event contains a TObjArray, which I believe may not be assumed to be suitable for re-use between subsequent GetEntry
calls. If the TObjArray member of the Event from a previous GetEntry
call is not suitable for re-use, I would assume a pre-allocated Event passed via SetBranchAddress
also cannot be assumed suitable. Then, who is constructing the TObjArray member in this case, and who is responsible for deleting it?