Object ownership
An object ownership means the permission to delete it.
Modern code should use local variables or std::unique_ptr
; but some of ROOT’s types are managed differently.
To prevent memory leaks and multiple attempts to delete an object, you need to know which objects are owned by ROOT and which are owned by you.
By the end of this page you will know why
shows an empty canvas after calling ownership()
.
Ownership by current directory gDirectory
When a histogram, a TTree
or a TEventList
is created, it is added by default to the list of objects in the current directory gDirectory
.
In many cases that is the TFile
that was opened most recently.
Example
Changing the directory of a histogram (same applies to trees and event lists):
You can remove a histogram from a directory by using SetDirectory(nullptr)
. Once a histogram is removed from the directory, it will not be deleted when the directory is deleted. Instead, you have to delete the histogram yourself to prevent memory leaks.
Disabling ROOT’s automatic ownership management for histograms
To prevent histograms from being added to the current directory, call the static function
Now you own all histogram objects and you will need to delete them, for instance through the use of std::unique_ptr
.
You can still set the directory of a histogram by calling SetDirectory()
once it has been created.
Example
When you create a TFile
object, it becomes the current directory (gDirectory
).
If you subsequently create a new histogram, this histogram is now owned by the current directory:
the histogram is deleted when the TFile
object destructed.
In the following example, only an empty canvas is shown because the TH1F
histogram is owned by the current directory (gDirectory
) corresponding to the TFile
object.
In the following example, the canvas shows the histogram because the TH1F
histogram is created before the TFile
is opened; the TFile
does not own it.
Finally, this canvas shows the histogram because it is owned by a unique_ptr
which lives longer than the function ownership()
:
Ownership by gROOT
The global gROOT
object has several utility collections, for instance of all functions gROOT->GetListOfFunction()
, canvases gROOT->GetListOfCanvases()
, and files gROOT->GetListOfFiles()
.
Objects that are members of these collections and are still “alive” during program tear-down are deleted by gROOT
.
If they get deleted earlier, they de-register themselves from TROOT
’s lists (“recursive remove”) to prevent double deletions.
Ownership by creating objects
When an object creates another, the creating object is often the owner of the created one. This will be documented in the function creating the other object.
Example
The call of Fit()
copies the global TF1
Gaussian function and attaches the copy to the histogram. When the histogram is deleted, the copy is deleted too.