Examine the stack

Hi,

this is a known problem with interpreted code using objects (not pointers) on the “stack” that are auto-deleted by ROOT. ROOT checks whether the TH1 is on the heap - it is, because that’s CINT’s only way to manage the interpreter stack. So then both ROOT and CINT try to delete the object. SetDirectory(0) is one option, using TH1* is another.

Cheers, Axel.

[quote=“Axel”]Hi,

this is a known problem with interpreted code using objects (not pointers) on the “stack” that are auto-deleted by ROOT. ROOT checks whether the TH1 is on the heap - it is, because that’s CINT’s only way to manage the interpreter stack. So then both ROOT and CINT try to delete the object. SetDirectory(0) is one option, using TH1* is another.

Cheers, Axel.[/quote]
Well, with his code you’ll probably have problems even in compiled mode (that’s what he was describing from the beginning). The problem seems to be inside TH1::operator = or TH1::Copy, which copies fDirectory member , after that TH1 dtor tries to do some calls:

if (fDirectory) {
      fDirectory->GetList()->Remove(this);
      fDirectory = 0;
   }

[quote]Well, with his code you’ll probably have problems even in compiled mode (that’s what he was describing from the beginning). The problem seems to be inside TH1::operator = or TH1::Copy, which copies fDirectory member , after that TH1 dtor tries to do some calls: [/quote]As mentioned by Axel, we do not because in the compiled code case, ROOT properly notice the object is on the heap and does not delete it at all.

Cheers,
Philippe.

:oops: I’ve realized the question had been answered . I duplicated the answer, and it is confusing. There is some excuse, I did type the answer yesterdays and hit the return button today :unamused:

[quote=“ytsen”]int main(int argc, char* argv[]) { { TH1F hData; TFile f("../MarIsolTau/histo.0607.W_Epvec.VT41.elmu.root","READ"); if (f.IsOpen()) { hData = * (TH1F*) f.Get("hElecTh"); }; hData.Print(); cout << "Going out of scope and crash now... " << endl; }; cout << "Done" << endl; return 0; };
[/quote]Each histogram object has the TDirectory owner. As soon as the owner is deleted its histogram are to be deleted too . In your case the TDirectory is TFile instance. You need to break the ownerships.
In fact, I see no reason to create the TH1F object 3 times in your code.
Very likely the code

int main(int argc, char* argv[]) { { TH1F *hData=0; TFile f("../MarIsolTau/histo.0607.W_Epvec.VT41.elmu.root","READ"); if (f.IsOpen()) { hData = (TH1F*) f.Get("hElecTh"); }; hData->Print(); cout << "Going out of scope and crash now... " << endl; }; cout << "Done" << endl; return 0; };will do what you really need. Pay your attention, you are not required to delete hData. The hData histogram is to be deleted automically as soon as TFile is deleted. Otherwise you have to break the TFile / TH1F relationships (see: root.cern.ch/root/html520/TH1.ht … tDirectory ) int main(int argc, char* argv[]) { { TH1F hData; TFile f("../MarIsolTau/histo.0607.W_Epvec.VT41.elmu.root","READ"); if (f.IsOpen()) { hData = *(TH1F*) f.Get("hElecTh"); hData.SetDirectory(0); // break the realtionships. }; hData.Print(); cout << "Going out of scope and crash now... " << endl; }; cout << "Done" << endl; return 0; };