Re: Histograms in gDirectory.

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri Jul 10 1998 - 08:53:15 MEST


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



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:34:34 MET