Crash when saving a TTree in multple TFiles

Hi everyone,

What is wrong with the following code:

int a = 0;
TTree *OptTree = new TTree("options", "options");
OptTree->Branch("a", &a, "a/I");
OptTree->Fill();
TFile *f1 = new TFile ("./test1.root", "recreate");
f1->cd();
OptTree->Write("test");
f1->Close();
TFile *f2 = new TFile ("./test2.root", "recreate");
f2->cd();
OptTree->Write("test");
f2->Close();

The first file test1.root works well. The second file test2.root seems to be corrupted. When I open the TTree, and plot the variables, I get:

Error in <TBasket::ReadBasketBuffers>: fNbytes = 353, fKeylen = 45, fObjlen = 778, noutot = 0, nout=0, nin=308, nbuf=778
Error in <TBranch::GetBasket>: File: test2.root at byte:220, branch:a, entry:0, badread=1, nerrors=1, basketnumber=0

Any idea?

Try

int a = 0;
TTree *OptTree = new TTree("options", "options");
OptTree->SetDirectory(0);
//...

Thanks for the quick answer! It does solve my problem but I’m not sure why.

@pcanal I knew about object ownership but I don’t understand what is wrong here. The TTree is created before opening any file. It should not be owned by the first or second file.

The difference between the cases with and without

OptTree->SetDirectory(0);

and that ‘without’ the TTree is associated with the current directory at the time creation (In your example this is gROOT itself). Internally the TTree code behaves differently whether or not its attached to a TDirectory (and ‘forget’ to check whether this directory is a file or just an in-memory directory like gROOT). Because of that, in the case where the TTree is attached to gROOT after the first call to Write it deletes from memory the TBaskets (ie. the data which has now been copied to the disk) and thus the 2nd Write does not do anything (and wrongly remembers the location of the baskets but in the wrong file).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.