Hi Rooters,
I was trying to fix some memory leaks in my analysis and ran into some trouble.
For the analysis I get several waveforms (TH1F) which are plotted in a TCanvas and stored in a TFolder.
The problem is that if I delete the TCanvas the TH1F stays in the memory as it is not owned by the TCanvas.
Is there a way to delete a TH1F which is drawn in a TCanvas by deleting the TCanvas?
In the attached code I add all the TCanvas to the TFolder and push them into a vector. After writing the TFolder to a TFile I use the vector to loop and delete all the TCanvas canvas. The same is done for the vector of TH1F which is fine in the example but get out of hand if i start ploting severals TObjects in one TCanvas.
Is there a way to delete a TCanvas which is added to the TFolder?
Thanks for your help in advance.
Cheers,
Christian
//C++
#include <iostream>
#include <sstream>
//ROOT
#include "TROOT.h"
#include "TH1F.h"
#include "TCanvas.h"
#include "TFile.h"
#include "TFolder.h"
int main(int argc, char*argv[]){
TH1F* th1;
TFolder* tf_th1 = new TFolder("tfolder","tfolder");
std::vector<TCanvas*> v_c1;
std::vector<TH1F*> v_th1;
for(int i=0;i<4000;i++){
std::cout << i << "\r";
std::cout.flush();
std::stringstream ss_th1;
ss_th1 << "Name_" << i ;
th1 = new TH1F(ss_th1.str().c_str(),ss_th1.str().c_str(),50000,0,50000);
for(int j=0;j<50000;j++){
th1->Fill(j);
}
std::stringstream ss_c;
ss_c << "c_" << i ;
TCanvas* c1 = new TCanvas(ss_c.str().c_str(),ss_c.str().c_str(),800,1000);
th1->Draw();
tf_th1->Add(c1);
v_c1.push_back(c1);
v_th1.push_back(th1);
}
std::cout << "here the memory is at a high level" << std::endl;
std::cout << "Press ENTER to continue....." << std::endl;
std::cin.ignore(1);
// create a root file to store the TFolder containing all TCanvas
TFile* tFile = new TFile("memoryTest.root","RECREATE");
tFile->cd();
tf_th1->Write();
tFile->Close();
delete tf_th1; // delete the TFolder
std::cout << "data is stored, memory is at a high level" << std::endl;
std::cout << "Press ENTER to continue....." << std::endl;
std::cin.ignore(1);
for(unsigned int i=v_c1.size()-1;i>0;i--){
delete v_c1.at(i);
}
std::cout << "size of v_c1 " << v_c1.size();
v_c1.clear();
std::cout << " " << v_c1.size() << std::endl;
std::cout << "removed vector of TCanvas, memory is at a high level" << std::endl;
std::cout << "TCanvas does not own the TH1 in it thus they are not deleted" << std::endl;
std::cout << "Press ENTER to continue....." << std::endl;
std::cin.ignore(1);
for(unsigned int i=v_th1.size()-1;i>0;i--){
delete v_th1.at(i);
}
std::cout << "size of v_th1 " << v_th1.size();
v_th1.clear();
std::cout << " " << v_th1.size() << std::endl;
std::cout << "removed vector of TH1, memory is back to low level" << std::endl;
std::cout << "Press ENTER to continue....." << std::endl;
std::cin.ignore(1);
delete tFile;
std::cout << "TFile pointer finally also removed" << std::endl;
std::cout << "memory is at back to low level" << std::endl;
std::cout << "Press ENTER to continue....." << std::endl;
std::cin.ignore(1);
}