Re: Ownership

From: James Patrick Burke <phjpb_at_slac.stanford.edu>
Date: Sat, 9 Oct 2010 11:33:46 -0700

Thanks for the clarification Philippe,

Jim.

On Fri, 8 Oct 2010, Philippe Canal wrote:

> > Is there any way for me to know whether the pointer returned to me (by, in
> this case, createHistogram()) points to an address on the heap?
>
> There are ways, however there are not portable and a bit brittle. More
> importantly, in this case, you do not need to worry about it.
> If createHistogram was to return a value that is not 'on the heap' this would
> be a serious bug in the implementation of createHistogram
> as this histogram would be gone before you could even use it.
>
> Cheers,
> Philippe.
>
> On 10/8/10 5:27 PM, James Patrick Burke wrote:
>>
>> Hi Rene,
>>
>> Thank you for your quick reply.
>>
>> I use h->SetDirectory(0) to remove my histo from gDirectory, which gives me
>> the same result as your suggestion.
>>
>> (If you have a spare 60 secs, would you mind checking the reasoning in my
>> very short attached macro?)
>>
>> And, as you say, having removed my histo from gDirectory, it is my
>> responsibility to delete it when I've finished with it.
>>
>> But just one question:
>>
>> TH1* h = pdf->createHistogram(hName,*x,Binning(20));
>> h->SetDirectory(0);
>> delete h;
>>
>> Is there any way for me to know whether the pointer returned to me (by, in
>> this case, createHistogram()) points to an address on the heap? I
>> presumably would not want to call delete if the address is on the stack.
>>
>> Thanks again,
>>
>> Jim.
>>
>>
>> root [0] .x jimMacro.C
>>
>> RooFit v3.12 -- Developed by Wouter Verkerke and David Kirkby
>> Copyright (C) 2000-2009 NIKHEF, University of California &
>> Stanford University
>> All rights reserved, please read
>> http://roofit.sourceforge.net/license.txt
>>
>>
>> Before h->SetDirectory(0) call:
>>
>> Address pointed to by h = 0x1897200
>> Address pointed to by p = 0x1897200
>>
>> After h->SetDirectory(0) call:
>>
>> Address pointed to by h = 0x1897200
>> Address pointed to by q = 0
>>
>> root [1]
>>
>>
>> ---and here's jimMacro.C (also attached):
>>
>> using namespace RooFit;
>>
>> void jimMacro()
>> {
>> // Set up p.d.f.
>> TString xName("x");
>> RooRealVar *x = new RooRealVar(xName,xName,-3.0,3.0);
>> RooRealVar m("m","m",0.0), s("s","s",1.0);
>> RooAbsPdf *pdf = new RooGaussian("pdf","pdf",*x,m,s);
>>
>> // Create histo from p.d.f.
>> TString hName("h");
>> TH1* h = pdf->createHistogram(hName,*x,Binning(20));
>>
>> // As I understand it, h is owned by the current directory (gDirectory)
>> TString pName(hName); pName += "__"; pName += xName;
>> TH1 *p = (TH1*)gDirectory->GetList()->FindObject(pName);
>>
>> // Check that the object was found
>> cout << "\nBefore h->SetDirectory(0) call:\n" << endl;
>> cout << "Address pointed to by h = " << h << endl;
>> cout << "Address pointed to by p = " << p << endl;
>>
>> // Remove from directory
>> h->SetDirectory(0);
>>
>> // Should no longer be able to find in gDirectory
>> TString qName(pName);
>> TH1 *q = (TH1*)gDirectory->GetList()->FindObject(qName);
>> cout << "\nAfter h->SetDirectory(0) call:\n" << endl;
>> cout << "Address pointed to by h = " << h << endl;
>> cout << "Address pointed to by q = " << q << endl << endl;
>>
>> // It is now my responsibility to delete h when I've finished with it
>> delete h; h = NULL; p = NULL;
>>
>> // Tidy up other stuff
>> delete x; x = NULL;
>> delete pdf; pdf = NULL;
>> }
>>
>>
>> On Fri, 8 Oct 2010, Rene Brun wrote:
>>
>>> Hi Jim,
>>>
>>> If you do not understand the Object Ownership chapter (::), I suggest to
>>> add
>>> TH1::AddDirectory(kFALSE) at the beginning of your script or session.
>>> After this call, it is up to you to manage your histograms and delete them
>>> when appropriate.
>>>
>>> Rene Brun
>>>
>>> On 08/10/2010 07:05, James Patrick Burke wrote:
>>>>
>>>> ROOT version: 5.26/00
>>>> Machine: MacBook (intel), Mac OS X (10.5.8)
>>>>
>>>> Hello,
>>>>
>>>> I have, in my code, a function containing the lines:
>>>>
>>>> TH1* h_data = data_->createHistogram("h_data",*x_,Binning(numBins_));
>>>> TH1* h_func = pdf->createHistogram("h_func",*x_,Binning(numBins_));
>>>>
>>>> (data_ is a RooDataSet*, pdf is a RooGaussian*, x_ is a RooRealVar*).
>>>>
>>>> If I call this function more than once I get the warning
>>>>
>>>> Warning in <TROOT::Append>: Replacing existing TH1:
>>>> h_data__numDegDaysBranch (Potential memory leak).
>>>> Warning in <TROOT::Append>: Replacing existing TH1:
>>>> h_func__numDegDaysBranch (Potential memory leak).
>>>>
>>>> when running.
>>>>
>>>> I believe RooAbsReal::createHistogram(...) is the method being called,
>>>> and from
>>>> http://root.cern.ch/root/html/RooAbsReal.html#RooAbsReal:createHistogram%2,
>>>> I'm told "The caller takes ownership of the returned histogram".
>>>>
>>>> Does this mean that I take ownership, or my data_ and pdf objects take
>>>> ownership?
>>>>
>>>> Either way, I want to avoid a memory leak and so should presumably call
>>>> delete somewhere.
>>>>
>>>> (I'd prefer not to delete data_ and pdf.)
>>>>
>>>> I've read Chapter 8 (Object Ownership) of the Users Guide, but I'm afraid
>>>> I don't really follow it :-(
>>>>
>>>> If somebody could point out how I can avoid this memory leak, I'd be very
>>>> much obliged.
>>>>
>>>> (Would simply varying the first argument ("h_data" or "h_func", above) of
>>>> createHistogram() every time I call my function do the trick?)
>>>>
>>>> Sincerely,
>>>>
>>>> Jim.
>>>>
>>>>
>>>
>
Received on Sat Oct 09 2010 - 20:33:57 CEST

This archive was generated by hypermail 2.2.0 : Sun Oct 10 2010 - 11:50:02 CEST