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