Segfault after deleting TObjArray

Hi all.

I am completely at a loss with the following situation. I open a file, read in a TTree, pass the TTree to a subroutine, which then reads in the leaves of the single branch and puts them into a TObjArray.
Upon deleting the TObjArray the program crashes.

I attached a minimal example for your convenience.

The files necessary to run and compile the program are
(1) all --> compiles the source file test.cxx
(2) sample.root --> sample root file with one branch and some leaves
(3) test.cxx --> file that needs to be compiled.

I do not understand why it would give a segfault after deleting the TObjArray.

With best regards,

Maurits
test.tar (10 KB)

Why do you delete the TObjArray holding the list of branches?
This data structure is owned by the Tree and is automatically destroyed when you delete the tree. You should not delete it yourself.

Rene

Hi.

Thanks for the fast reply. I always thought any explicitly with “new” created object must be destroyed (following good C++ practice).
I already had the suspicion that TTree must be related to the TObjArray in some way. I do not understand why that is though. If alternatively I would create a classical array on the heap as e.g.
TLeaf *leaf = new TLeaf[10];
and then later delete it with
delete [] leaf;
would that give a segfault as well? I thought not.
So why is TObjArray owned by the Tree, and where is that set explicitly.

Sorry for the nagging questions.

Maurits

As the name suggests Trees have Branches and Branches have Leaves. The Tree
must know how to navigate in its data structures. You cannot have branches or leaves floating around (except in Autumn!).

To access the branches or leaves you do not have to create them. You only need to access them.

Rene

I agree. However, I do need to create the structures of the Tree, i.e. the branches and leaves. I do so e.g. with

TBranch *branch = new TBranch(); branch = tree->GetBranch("branchname");
Deleting the branch with

will be just fine.

So then I still do not understand why TObjArray, which just holds the pointers to TObjects (and in this case to the leaves), is somehow “owned” by the Tree.

If I have SetOwner(kFALSE) and the elements are not actually owned by the TObjArray then deleting the TObjArray should be just fine. Or am I missing something?

Hi,

You do not need to create the TBranch object (and in most case the required type is not even TBranch but TBranchElement), TTree::Branch does create the branch object as needed.

[quote]So then I still do not understand why TObjArray, which just holds the pointers to TObjects (and in this case to the leaves), is somehow “owned” by the Tree. [/quote]So that the user of the TTree does NOT have to worry about cleaning up all the bits of pieces (most of which you are not even aware of), the TTree explicitly, intentionally, by design, owns the branch and the leaf objects and absolutely require those objects to be ‘alive’ until the TTree destructor is ran. (i.e. this is just good C++ design). In other word the creation and deletion of the TBranch is an implementation details that you should not worry about.

There is almost no cases where you would want or need to call new TBranch yourself (and thus no need to delete it).

For additional discussion on some of the ownership rules in ROOT, please re-read the User’s Guide chapter on object ownership.

Philippe.

Hi Philippe.

Thanks for clearing that up. I must admit that I only briefly skimmed through the part on object ownership. I shall catch up on that.
Again, a thanks to you and Rene for your patience.

Cheers,

Maurits