Re: Histograms in gDirectory.

Rene Brun (Rene.Brun@cern.ch)
Fri, 10 Jul 1998 08:53:15 +0200


Alexander Yuryevich Zvyagin wrote:
>
> Dear ROOTers,
>
> I'd like to discuss one feature of the TH1 class: how the member function
> void TH1::Build() works. (You'll find the function body at the end of this
> E-mail.) This function is called when TH1 constructor is invoked.
>
> // Example 1.
> TH1F a("E",....), b("E",....);
>
> This is *good* C++ code and this is *bad* ROOT code.
> What will ROOT do?
> The histogram a("E",...) is created and added
> (See TObject::AppendDirectory()) to the current directory. On default it
> is gDirectory. OK, you have histogram 'a'. Then ROOT will try to create
> histogram b("E",...) with the *same* name "E" as the histogram 'a' has.
> ROOT will find that object with the same name already exists in the
> gDirectory and it'll try to *delete* it. So ROOT will delete pointer to
> statically allocated object. Something like this:
> {
> int a;
> int *b = &a;
> delete b;
> }
> This is bad thing. Your *good* C++ code will crash. I think this is
> ROOT bug.
>
> There are several ways how to write better code.
> 1. Use pointers: TH1F *
> 2. Test that there isn't object with the same name in the gDirectory.
> 3. Create your own TDirectory structure.
> 4. Use next code:
>
> // Example 2.
> TDirectory *gDirectory_save = gDirectory;
> gDirectory=NULL; // ROOT assumes that NULL==0
> TH1F a("E",....), b("E",....);
> gDirectory=gDirectory_save;
>
> This mechanism simply turn off the inserting of histograms in the list
> list of gDirectory objects.
>
> Comments?

Alexander,
You are partially right. As Pasha pointed out, Root is protected
against destruction of objects not allocated via new.
I have updated my new version to simply remove an existing histogram
from the list of objects in memory in case you create a new histogram
with the same name. I have left the Warning message to indicate
a possible memory leak.

Remarks.
- Always use the new operator to create objects. This will solve
many problems in case you execute repetitively macros in
the global scope.
- Instead of using your solution with gDirectory, use the existing
function TH1::SetDirectory.
hist->SetDirectory(0) removes hist from the list of objects
in the current directory.
hist->SetDirectory(newdir) removes hist from the current directory
and instead, inserts it into directory newdir.

Rene Brun