Write in a file without memory leak

From: David Gourio (gourio@gsi.de)
Date: Wed Mar 31 1999 - 16:49:57 MEST


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