Re: [ROOT] TDirectories and C-arrays

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Aug 11 2000 - 21:22:36 MEST


Hi Georges,
The solution is simply to add 
 fHists[i]->SetDirectory(0);
after the statement
      fHists[i].Streamer(buf);

If you take the responsability for the bookeeping, it is your
responsability to delete the corresponding objects.

Rene Brun

On Fri, 11 Aug 2000, George Heintzelman wrote:

> 
> Rooters,
> 
> I recently started running into many errors when exiting ROOT, of the 
> form:
> 
> #Fatal in <operator delete>: unreasonable size (1110139808)
> #aborting...
> 
> I assumed that this was my problem and tried to hunt it down. Well, I 
> finally did, but it's not just my problem. Here's the problem, as best 
> I can describe it.
> 
> I have a class that deals with many histograms all at once. This class 
> has a data member fHists which is an array of TH1F allocated with 
> operator new[]:
> 
> TH1F *fHists;  // In class definition
> fHists = new TH1F[Length()];  // In constructor
> 
> When an object of this class is destroyed, it correctly calls operator 
> delete[] on fHists to clean up after itself. So far, so good. But, in 
> the streamer, there is code like this:
> 
> // Read in the length
> fHists = new TH1F[Length()];
> for (int i = 0; i < Length(); ++i) {
> 	fHists[i].Streamer(buf);
> }
> 
> and, as readers of roottalk will be aware, that Streamer call will put 
> the TH1F into the gDirectory (usually the file/subdirectory being read 
> from). Now comes the gotcha: if you fail to delete an fData (say, you 
> read it in from file and did some interactive work with it), when ROOT 
> shuts down, it will go through its still-open gDirectory and delete all 
> the undeleted objects -- but it will use operator delete, NOT operator 
> delete[]! This in turn causes Root's operator new/delete builtin 
> protections to activate, causing the fatal error.
> 
> This is even more of a big deal because it doesn't only happen when 
> shutting down root -- you can trigger it also by doing a Close() on the 
> TFile.
> 
> At the moment, I can see two potential solutions, both of which have 
> drawbacks, but from which I am probably going to select.
> 1) Protect the TH1F's from being put in the directory by setting 
> gDirectory to 0. My interactive users don't like this option, because 
> they like the convenience of being able to specify some from this arry 
> of histograms by name, and will probably in at least some cases pull 
> the histograms explicitly into a TDirectory, which causes more problems.
> 2) Add the object containing the TH1F's also to the gDirectory (ahead 
> of its members) so that it gets cleaned up before its members, since it 
> knows how to clean them up correctly. This doesn't completely solve the 
> problem either, since I need to know all the implementation details of 
> TH1F in order to know all the places where I will have to add/remove 
> this object from a Directory in order to protect its members. And, it's 
> still possible for users to circumvent this protection when the 
> top-level object isn't (yet) in the directory.
> 
> The best solution, of course, would be for the Root team to either:
> a) decide that TDirectorys should not own (and therefore delete) their 
> contents, since it is just too easy to Add an object to a directory, 
> then delete it and forget to Remove it. I don't see a huge problem with 
> this solution, but it is a potentially significant change deep in the 
> guts of ROOT...
> b) make it possible for TDirectories to tell the difference between new 
> and new[]'d objects added to the directory, and not delete the latter 
> (or delete only the zeroth element in the array).
> c) supply functionality for 'all of an array' of TObject things to be 
> pulled into a TDirectory which will then do the delete[] correctly, in 
> which case I can put protective code around the readin and explicitly 
> put the array into gDirectory myself.
> 
> George Heintzelman
> gah@bnl.gov
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:31 MET