I’m attempting to be a good steward of the pointers I make in my C++ code; however, I’m having difficulty cleaning up the ROOT objects without crashes.
In my code I instantiate new ROOT objects on my own, without reading from a file or being the return of another call. For example: new TH1F(“name”, “title”, bins…)
I believe from the forum topics and ownership documentation that in this case I should be responsible for calling the ‘delete’ on these objects, but that is crashing my application.
Setting the kCanDelete and kMustCleanup bits doesn’t change the behavior. Incidentally, if I try to call TH1::SetDirectory(0), TH1::Reset(), or TH1::Delete() it also crashes in a manner similar to the ‘delete’ call. I’ve not been able to learn if this is related to my issue. I’ve also tried calling TH1::AddDirectory(kFALSE) before instantiating any new objects, but that doesn’t prevent crashes either. I initially suspected that something else is deleting my instances, so I was trying the various methods above to prevent that by trying to declare my code as the owner.
Any pointers (pun intended) on where I could look?
Unfortunately my code isn’t simple enough to paste in as a snippet in a forum. I will try to work up a simpler example that still causes the problem.
I do read histograms from files, but the TH1 and TF1 I’m having problems deleting right now weren’t read from or written to files, so I don’t believe that the TFile holds ownership of the pointer. I did read in the documentation where TFile will manage the lifecycle of pointers associated with it though. I’ll take another look to be sure I’m not missing something with these objects getting written to files I wasn’t expecting. I know they aren’t read from the files as I do a ‘new’ call to create them.
Note that the “hh” (“a”) histogram in ksmith’s example was NOT retrieved from the “f” file. It was NEWLY created (in a way that it became “connected” to the “f” file).
If you wanted to “disconnect” it from “f”, you would need to:
hh->SetDirectory(0); // (0) … or … (gROOT)
I’ve tried the SetDirectory(0) call unsuccessfully, too. In my original question, you’ll see where I noted calling that function (among others documented to let one manage ROOT pointers) actually causes a similar crash. I suspect this means that ROOT is trying to manage the TH1 and TF1 pointers for me somewhere else, but I’ve yet to figure out where that might be.
Is your program multithreaded, and is “Root.ObjectStat: 1” in your .rootrc file? This line enables some very thread unsafe code that happens in the constructor and destructor of every TObject, which could be causing your issue.
If the aim is to write an object to the file and then freeing the memory, functions would help.
Inside the main program, we open the file with “RECREATE” tag so that any previous file gets overwritten, then we just close it. Later we will update this file inside a function.