Object name and ownership

Dear all,

I’ve been using ROOT for a few years but it has not been clear yet for me
how ROOT manages objects.
I understand that objects derived from TNamed are named and one can
retrieve their pointers by indicating the name as key, using
TDirectory::FindOjbect() method and so on.

Now my question is,
the objects (in memory) are allowed to have same name and be owned by identical
directory or not.

I am using v3.10/01 on Linux.

Followings are a part of TH1::Build() function.

if (fgAddDirectory && gDirectory) {
TH1 hold = (TH1)gDirectory->GetList()->FindObject(GetName());
if (hold) {
Warning(“Build”,“Replacing existing histogram: %s (Potential memory lea
k).”,GetName());
gDirectory->GetList()->Remove(hold);
// delete hold;
}
gDirectory->Append(this);
fDirectory = gDirectory;

It seems that
when one attempt to create new histogram, another object with same
name is removed from object list of current directory.
(but not deleted. Is the old object accessible?)

But following examle shows that building new object(h_new) with
existing name(“h_name”) is warned but the old object(h_old) is still
belong to “test.root”, although pointer of h_old can no longer
be retrived by TDirectory::FindObject().

root [0] TFile f(“test.root”, “new”)
root [1] TH1F h_old(“h_name”, “title”, 10, 0, 10)
root [2] TH1F ptr = &h_old
root [3] ptr
(class TH1F
)0x89c2758
root [4] h_old.GetDirectory()->GetName()
(const char* 0x89c19a4)"test.root"
root [5] gDirectory->FindObject(“h_name”)
(const class TObject*)0x89c2758
root [6]
root [6] TH1F h_new(“h_name”, “title”, 100, 0, 100)
Warning in TH1::Build: Replacing existing histogram: h_name (Potential memory leak).
root [7] ptr
(class TH1F*)0x89c2758
root [8] gDirectory->FindObject(“h_name”)
(const class TObject*)0x8a29000
root [9] ptr->GetDirectory()->GetName()
(const char* 0x89c19a4)"test.root"
root [10] ptr = &h_new
(class TH1F*)0x8a29000
root [11] ptr->GetDirectory()->GetName()
(const char* 0x89c19a4)"test.root"
root [12] f.cd()
(Bool_t)1
root [13] gDirectory->FindObject(“h_name”)
(const class TObject*)0x8a29000
root [15] h_old.GetDirectory()->GetName()
(const char* 0x89c19a4)“test.root”

I am confused.
Could anyone explain this please?

Best regards,
Kame

Your example is simple and good enough to explain what happens.
When creating a new histogram (say TH1* hnew), with the same name “hname” as
an already existing histogram hold in the same directory, the old histogram hold is removed from gDirectory->GetList(),
BUT IT IS NOT DELETED. As simple as that.
See chapter about Object Ownership in teh Users Guide

Rene

Thank you for reply.

May I ask you two questions?

[1] If new histogram is created with existing name, old one is removed from gDirectory()->GetList, and no longer owned by any directories.
But TH1::fDirectory of old histogram keeps pointing the directory and TH1::GetDirectory() returns the pointer.
I feel this confuses the user.
TH1::fDirectory should be reset to NULL when the histogram is released from directory, shouldn’t it?

[2] So, just executing same line like,
root[] TH1F h(“name”, “title”, 10, 0, 10)
root[] TH1F h(“name”, “title”, 10, 0, 10)
cause memory leak.
But
root [] TH1F h(“name”, "tilte, 10, 0, 10)
root [] TH1F h2(“name”, “title”, 10, 0, 10)
or
root [] TH1F *h = new TH1F(“name”, “title”, 10, 0, 10)
root [] TH1F *h2 = new TH1F(“name”, “titlle”, 10, 0, 10)
is not memory leak because pointer or variable refering old histogram is saved and old histogram is accessible.
Am I right?

[quote]But TH1::fDirectory of old histogram keeps pointing the directory and TH1::GetDirectory() returns the pointer.
I feel this confuses the user. [/quote]
I think you are right, we will update to set the directory of the old histogram to 0.

[quote]root [] TH1F *h = new TH1F(“name”, “title”, 10, 0, 10)
root [] TH1F *h2 = new TH1F(“name”, “titlle”, 10, 0, 10)
is not memory leak because pointer or variable refering old histogram is saved and old histogram is accessible.[/quote]
It is not a memory leak if and only if you have the corresponding

delete h; /* necessary since no directory owns it anymore */ delete h2; /* optional since a directory owns it */
Cheers,
Philippe.