Segmentation Fault in Recursive Removement

I wrote a class which does the automatic saving of histograms/graphs, etc. to a certain folder including a pavetext to each canvas, such that I am able to reconstructor which version of the code was used to create the png/root-file.
When using this class I 've segfaults because of the recursive removement of ROOT:
Here is the code I use

void HistogrammSaver::SaveHistogramPNG(TH1* histo) { if(histo->GetEntries()==0){ cout<<"Histogram "<<histo->GetName()<<" has no entries..."<<endl; return; } stringstream histoName; histoName<<histo->GetName()<<"_Clone"; TH1* htemp=(TH1*)histo->Clone(histoName.str().c_str()); if(htemp==0)return; TCanvas *plots_canvas = new TCanvas("plots_canvas","plots_canvas"); plots_canvas->cd(); htemp->SetMinimum(0.); htemp->Draw(); stringstream ptName; ptName << "pt_"<<histo->GetName(); TPaveText* pt2 = (TPaveText*)pt->Clone(ptName.str().c_str()); pt2->Draw(); ostringstream plot_filename; plot_filename << plots_path << histo->GetName() << ".png"; plots_canvas->Print(plot_filename.str().c_str()); delete plots_canvas; }

When doing the last step: delete plots_canvas
there are intermittent seg faults.
I don’t have any idea what could be wrong.
I started to Clone the Histos and the PaveText because of that problem but it doesn’t help…
Any idea? What is wrong with that code?

If I do not delete the canvas at the end, it works but I got the warning that I am overriding an existing canvas…


What’s “pt”? Where does it come from?
Note: cloned objects will not be automatically deleted (so you delete them “manually” after you no longer need them, e.g. after you “delete plots_canvas;”).
Another note: instead of fighting with “stringstream” and “ostringstream”, try simply:
SomeThing->Clone(TString::Format(“MyNewPrefix_%s”, histo->GetName()));
SomeThing->Print(TString::Format("%s.MyNewSuffix", histo->GetName()));
Also: try to add another sanity check in the beginning:
if (!(histo && histo->GetEntries())) {

In worst case, try this brutal fix (do NOT “delete plots_canvas;”):

TCanvas *plots_canvas = ((TCanvas *)(gROOT->GetListOfCanvases()->FindObject("plots_canvas"))); if (plots_canvas) plots_canvas->Clear(); else plots_canvas = new TCanvas("plots_canvas", "plots_canvas");

pt is a Pavetext defined when creating the histogramsaver object:

TPaveText *pt; pt = new TPaveText(0.07,0,0.22,0.10,"NDC"); pt->Clear(); pt->SetTextSize(0.0250); pt->AddText(revisionString); pt->AddText(dateandtime.AsSQLString()); ...

I want to have it in every Canvas i create.

Since i had this strange seg faults and I it was revering to RecursiveRemoving, I decided to use just use Clones of all Objects.

So what exactly happens if i delete the canvas? Does it delete all obejcts which i ve drawn on that canvas?
Are the objects i draw in that canvas somehow connected to the Canvas?


[quote=“Wile E. Coyote”]In worst case, try this brutal fix (do NOT “delete plots_canvas;”):

TCanvas *plots_canvas = ((TCanvas *)(gROOT->GetListOfCanvases()->FindObject("plots_canvas"))); if (plots_canvas) plots_canvas->Clear(); else plots_canvas = new TCanvas("plots_canvas", "plots_canvas");[/quote]

This brute force change does not help a lot. With this change, the plot range and everything else isn’t right anymore.
The y axis is just 0-1, the range of x is very strange…
.What could be the reason?


The easiest way to track this down is use valgrind to run your example:valgrind root.exe ....


valgrind --tool=memcheck --leak-check=full [–show-reachable=yes] [–num-callers=50] [–track-origins=yes] [–db-attach=yes] --suppressions=root-config --etcdir/valgrind-root.supp root-config --bindir/root.exe -l -q 'YourMacro.cxx[++][(Any, Parameters, You, Need)]'
valgrind --tool=memcheck --leak-check=full [–show-reachable=yes] [–num-callers=50] [–track-origins=yes] [–db-attach=yes] --suppressions=root-config --etcdir/valgrind-root.supp YourExecutable [Any Options You Need]
and especially carefully study messages that appear in the beginning of the output.
(Note: the “–show-reachable=yes” option will give you too many warnings, I believe.)