How to delete a TTree pointed to by an element of a vector?

Hi All,

As part of a large code I need to temporarily store pointers to trees in an std::vector. After I’m done with the tree I’d like to delete it so that memory can be reallocated. However when I call delete on an element in the array ROOT crashes.

Here is code which illustrates the problem.

#include <iostream> #include <vector> void breakOnDelete(){ std::vector<TTree*> vec; for (int i=0; i<10; i++){ vec.push_back(new TTree()); } cout <<"vec is of size: " <<vec.size() <<endl; for (int i=0; i<10; i++){ delete vec[i]; } }

This causes ROOT to crash comlaining that:
*** Error in `/home/chris/root/bin/root.exe’: double free or corruption (out): 0x00007fe9088d7b50 ***
before the backtrace is printed.

I’m I doing something improper here?

On a related note…I’ve also tried using TTree::Delete() on a vector element: vec[i]->Delete(). But this deletes the ENTIRE vector! Am I misunderstanding how it is supposed to work?

Thanks,
Chris

What do you do with these “temporary” TTrees? Where do they come from? Where do they go to?
Do remember that any TTree that is “associated” with a ROOT TFile will automatically be deleted as soon as you close / delete that TFile.

Well the code I posted above shows that this a more general problem since the trees are not loaded from a file.

But in my larger code I am using TTree::CopyTree() with a char* selection to pick out entries based on event criteria. I’m sure that I’m not closing the file the original tree is loaded from. Nor, for that matter, am I deleting the original tree…because that would delete all of its copies. 8)

-Chris

The example code that you posted does not work at all.
In an interpreted code one gets an “Error: Symbol vector<TTree*>vec is not defined in current scope”.
In a compiled code one gets an “error: ‘TTree’ was not declared in this scope”.
As soon as I add a #include “TTree.h”, I can use your example in a compiled code without problems.
Also, I get no problems when I replace “delete vec[i];” with “vec[i]->Delete();”.

BTW. See the “IMPORTANT:” notes in the TTree::CopyTree method description. I think that before you delete your “temporary” TTrees (i.e. the “copies”), you should delete your “mother” TTree (i.e. the “original”).

Well this is weird. If I put the code I posted above in a file named file.C I can run it in a root session just by doing:
.L file.C
breakOnDelete()

However, it breaks on the delete call just as I described. It also breaks if I do vec[i]->Delete(). I get the same behavior (it breaks on delete) whether I compile or not.

I’m using root v5.34.04 and gcc version 4.7.3. You?

Yes, one would need to #include <TTree.h> to compile the code…I should have put that in there.
And yes, I read the important notes in TTree::CopyTree() and I’m well within its boundaries.

-Chris

I tried ROOT 5.28/00h and 5.34/07. In both cases:
root [0] .L file.C
root [1] breakOnDelete()
Error: Symbol vector<TTree*>vec is not defined in current scope file.C:4:
*** Interpreter error recovered ***
root [2]

Okay…false alarm. This was not a root issue. I think the problem has its roots in the fact that a couple weeks ago I wiped my / partition and changed linux distros. ROOT is installed in my /home partition so it survived. When the linux install was over I immediately tried starting ROOT. Hey presto…it worked, I thought. #-o Having remembered I had done this, I rebuilt ROOT this morning and everything is working properly.

Thanks Wiley for the discussion! However, I still can’t duplicate the [quote]Error: Symbol vector<TTree*>vec is not defined in current scope file.C:4:
*** Interpreter error recovered ***[/quote]
error that you get when running in interpreter mode.

Happy Friday,
Chris