Re: Write in a file without memory leak

From: Rene Brun (Rene.Brun@cern.ch)
Date: Mon Apr 05 1999 - 16:10:30 MEST


Hi David,
If you look at the prototype of TFile::Open, you will see that this
is a static function returning a TFile object.
I have modified your function ProcessFile such that you do not get
a memory leak.

Rene Brun


void ProcessFile(char * RootFileName) { 
  
  TFile *RH_File;

  // Dummy histogram to be written in the root file
  TH1F DummyHisto("Dummy", "I am empty", 100, 0., 1.);   

  // Open the file, take care if it already exists
  if (Lili.AccessPathName(RootFileName) ) {
    // File does not exist yet.
    RH_File = new TFile(RootFileName,"CREATE","Gros appetit");
  }
  else {
    // File already exists
    RH_File = new TFile(RootFileName,"UPDATE");  
  }

  // Write down in the file the dummy histogram, overwrite instead of
  // creating a new version of the object
  DummyHisto.Write(DummyHisto.GetName(), TObject::kOverwrite);

  RH_File->Close();
  delete RH_File;
}


On Wed, 31 Mar 1999, David Gourio wrote:

> Hi Rooters,
> 
> In the following example, I just open a root file, write down a dummy
> histogram and close it. I avoid any dynamical allocation. 
> THF1 and TFile are declared in a subfunction of the main program (and not
> as static), they are consequently local and have a lifetime related to the
> execution of the function.
> Nevertheless, the allocated memory gets larger as I reexecute the
> function (if I have well understood how TStorage works).
> 
> By looking closely at the created root classes, I see that some classes
> remain on the heap, mainly originating from the histogram..., but also
> from the TFile.
> I have removed them by hand, but it doesn't even really help.
> 
> So is it a bug (from me?) or a feature ? In both cases, how to
> properly clean the memory ?
> 
> The source file should be compiled with a standart Makefile
> I use version 220 of Root.
> 
> Thanks,
> best regard,
> 
> David Gourio
> ========================================================================
> Mail   : GSI, Abteilung KP3 D-64291 Darmstadt    
> E-Mail : D.Gourio@gsi.de
> Phone  : +49 6159 71 27 79 
> Fax    : +49 6159 71 29 89
> 
> 
> 
> 
> ------------------------------Source---------------------------------
> #include <iostream.h>
> 
> #include <TROOT.h>
> #include <TUnixSystem.h>
> #include <TH1.h>
> #include <TFile.h>
> 
> 
> char * PrintBool(Bool_t MyBoolean) {
>   if (MyBoolean) return "True";
>   else           return "False";
> }
> 
> void ProcessFile(char * RootFileName) {	
>   
>   TUnixSystem Lili;
> 
>   TFile RH_File;
> 
>   // Dummy histogram to be written in the root file
>   TH1F DummyHisto("Dummy", "I am empty", 100, 0., 1.);   
> 
>   // Open the file, take care if it already exists
>   if (Lili.AccessPathName(RootFileName) ) {
>     // File does not exist yet.
>     RH_File.Open(RootFileName,"CREATE","Gros appetit");
>   }
>   else {
>     // File already exists
>     RH_File.Open(RootFileName,"UPDATE");  
>   }
> 
>   // Write down in the file the dummy histogram, overwrite instead of
>   // creating a new version of the object
>   DummyHisto.Write(DummyHisto.GetName(), TObject::kOverwrite);
> 
>   RH_File.Close();
> }
> 
> 
> 
> int main() {
> 
>   TROOT MyRoot("xx", "xx xx");
> 
>   // For checking the objects still in memory...
>   TObject * obj;
>   TIter * AllClassesList;
> 
>   // Root file name
>   char * RootFileName="gargantua.root";
> 
>   // Create and enable statistics of the heap
>   TStorage MyHeap;
>   MyHeap.EnableStatistics();
> 
>   // Print out the memory state once before
>   cout << "Before\n";
>   MyHeap.PrintStatistics();
> 
> 
>   // Main loop : write 10 times in the file
>   for ( int i_loop=0 ; i_loop<10 ; i_loop++ ) {
> 
> 
>     // Open, fill and close the root file
>     ProcessFile(RootFileName);
> 
> 
>     // Print out the memory state
>     cout << "After " << i_loop+1 << " pass\n";;
>     MyHeap.PrintStatistics();
> 
> 
>     // Print out list of root classes 
>     cout << "------List of current root classes----------\n";
>     AllClassesList = new TIter(MyRoot.GetListOfClasses());
>     while ( (obj = AllClassesList->Next()) ) {
>       cout << obj->GetName()             << " " 
> 	   << "On Heap:" << PrintBool(obj->IsOnHeap()) << "   "
> 	   << "Zombie:" << PrintBool(obj->IsZombie()) << endl;
>     }
>     delete AllClassesList;
> 
>   }
> 
> 
> 
>   // Print out list of root classes and delete them
>   cout << "--------List of current root classes----------\n";
>   AllClassesList = new TIter(MyRoot.GetListOfClasses());
>   while ( (obj = AllClassesList->Next()) ) {
>     cout << obj->GetName()             << " " 
> 	 << "On Heap:" << PrintBool(obj->IsOnHeap()) << "   "
> 	 << "Zombie:" << PrintBool(obj->IsZombie()) << endl;
>     // Suppress all classes on the heap 
>     delete obj;
>   }
>   delete AllClassesList;
> 
> 
> }
> 
> 
> 
> 



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