[vtkusers] Understanding vtkSmartPointers
Andrew Maclean
andrew.amaclean at gmail.com
Wed May 30 17:27:06 EDT 2018
Marcus
Take your time there is no compulsion to produce an example. It is a
case of .... 'Hmmm this may be a good example, when I have time I "may" do
one one day'. I also think you should be demonstrating current best
practice with the caveat that all tests pass. After all, we learn from the
examples, and how else can you showcase new and great features of VTK?
Elvis, I agree with you here. However there is no point in a wholesale
reworking of existing code to use new and great features of VTK. As these
are examples for a broad audience, we should keep a wide variety of code
until it actually fails. Then fix it.
Bill, do you have any views here?
Regards
Andrew
On Thu, May 31, 2018 at 1:43 AM Elvis Stansvik <elvis.stansvik at orexplore.com>
wrote:
> Den ons 30 maj 2018 17:07Marcus D. Hanwell <marcus.hanwell at kitware.com>
> skrev:
>
>> Hi Andrew,
>>
>> To the best of my knowledge the examples require backward compatibility,
>> and so I couldn't show the "best" form for people who dislike calling
>> .Get() until the minimum is bumped to VTK 8.1.0 I think. Most of my work is
>> done on that, or even more recent SHAs, so I don't think about it too much.
>>
>> Is there an answer for this, can we make an example that requires 8.1+,
>> as we add more new features it seems like a reasonable request. I am really
>> swamped right now, but was hoping to get to some charting examples too.
>>
>
> Speaking as an outsider, I think it would be fine if the examples dropped
> the requirement that they be backwards compatible, and only show the best
> practice with current stable release. It's what I see in most other
> projects I've used, and I think people accept that they'll have do do some
> work to get examples working with old releases.
>
> Others probably disagree though :)
>
> Elvis
>
>
>> Thanks,
>>
>> Marcus
>>
>> On Tue, May 29, 2018 at 6:39 PM, Andrew Maclean <
>> andrew.amaclean at gmail.com> wrote:
>>
>>> Hi Marcus,
>>> This is a very clear and succinct explanation of the usage of
>>>
>>> vtkNew /
>>>
>>> vtkSmartPointer /
>>>
>>> vtkWeakPointer .
>>> If you have time would it be possible to do a nice C++11 demonstration
>>> example to be added into VTK Examples?
>>> I have a suspicion that this will be an issue arising again and again.
>>>
>>> I'll be glad to help.
>>>
>>> Personally (like Bill) I have never liked: .GetPointer()/.Get() in
>>> vtkNew so I haven't used it much. However ... since it implicitly returns
>>> the pointer now, I'll probably use it more.
>>>
>>> Rgeards
>>> Andrew
>>>
>>>
>>>
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: "Marcus D. Hanwell" <marcus.hanwell at kitware.com>
>>>> To: Fcs <ftpronk at engits.com>
>>>> Cc: VTK Users <vtkusers at vtk.org>
>>>> Bcc:
>>>> Date: Mon, 28 May 2018 10:12:24 -0400
>>>> Subject: Re: [vtkusers] Understanding vtkSmartPointers
>>>> On Mon, May 28, 2018 at 7:43 AM, Fcs <ftpronk at engits.com> wrote:
>>>>
>>>>> Using VTK for one of our projects, we are encountering some memory
>>>>> leaks
>>>>> which, in time, cripple our system. So I'm trying to have a better
>>>>> understanding of the VTK pointers
>>>>> <https://blog.kitware.com/a-tour-of-vtk-pointer-classes/> .
>>>>>
>>>>> It was my (erroneous..?) belief that the *vtkSmartPointer*s would
>>>>> destroy
>>>>> the object they were holding when getting out of scope. Carefully
>>>>> reading
>>>>> the kitware blog post linked hereinabove, and playing around with a
>>>>> test
>>>>> code (code sample below), I now understand that it is objects held by
>>>>> *vtkNew* that will be destroyed when out-of-scope, and that
>>>>> *vtkSmartPointer*s, on the contrary, will keep them alive as long as
>>>>> the
>>>>> reference count is non-zero. Is this correct?
>>>>>
>>>>
>>>> No, that is not correct. The vtkNew class instantiates a vtkObject
>>>> derived instance and will decrement its reference count when it goes out of
>>>> scope. You can still store what was created by vtkNew in a vtkSmartPointer,
>>>> increasing the reference count to two, and keeping that object alive even
>>>> when the containing vtkNew goes out of scope.
>>>>
>>>> In its simplest form, if you don't use other smart pointer classes with
>>>> it then vtkNew acts much like a stack allocated object, where the object
>>>> created is automatically deleted when it goes out of scope. You must
>>>> remember that all vtkObject derived classes are implicitly reference
>>>> counted - it is built into the API. The smart pointer classes just take
>>>> care of incremementing/decrementing the reference count.
>>>>
>>>>>
>>>>> Now, from a practical point of view: does this mean that I can, in a
>>>>> class,
>>>>> create an entire VTK pipeline with *vtkSmartPointer*s, and only store
>>>>> the
>>>>> latest object in a member variable to keep every object alive (So, in
>>>>> my
>>>>> code below, only bookkeep the object returned by applyFilters())? And
>>>>> that
>>>>> when I'm finished, I can call ->Delete() on that object to clean-up the
>>>>> entire pipeline? Is this a good practice? Until now, I was
>>>>> painstakingly
>>>>> storing every object created for the lifetime of a pipeline, and I
>>>>> would
>>>>> like to know if I can simplify my code..
>>>>>
>>>>> In my opinion you should aim to never call Delete, but to have a smart
>>>> pointer contain the things needed. I think all pipeline API will increase
>>>> the reference count, and so you only usually need to keep a reference to
>>>> the pipeline objects you are going to keep around/use. The debug leaks code
>>>> will help you verify you got it right.
>>>>
>>>> I would add that we have found in bigger applications that a passing
>>>> debug leaks is not always enough, ensuring objects are deleted when they
>>>> are done with is more difficult but necessary, especially in graphical
>>>> applications that might run for some time. My honest summary of using the
>>>> smart pointers (in classes, local code, etc) is:
>>>>
>>>>
>>>> vtkNew - when you will instantiate the object, and want to keep a
>>>> strong reference (you can't change what instance a vtkNew variable points
>>>> to)
>>>>
>>>>
>>>> vtkSmartPointer - when you might create, or use an instance passed in,
>>>> and ensure it stays around for when you want to make calls. Assigning a
>>>> different instance to one will decrement the one it points to before
>>>> switching it to point to the new instance and incrementing.
>>>>
>>>>
>>>> vtkWeakPointer - when you want to call API if something is still
>>>> around, check for nullptr before using, will not affect reference count.
>>>>
>>>> I think I wrote something similar back then. Whenever I see code like
>>>>
>>>> vtkSmartPointer<vtkRenderer> renderer =
>>>> vtkSmartPointer<vtkRenderer>::New();
>>>>
>>>> I want to replace it with
>>>>
>>>> vtkNew<vtkRenderer> renderer;
>>>>
>>>> It does the exact same thing with no repetition, and is clearer. The
>>>> examples require backwards compatibility with older VTK, and I don't think
>>>> Bill liked calling .GetPointer()/.Get() on the vtkNew object. You no longer
>>>> have to do that, but it is a more recent addition to the vtkNew API - it
>>>> will implicitly return the pointer to the contained object as
>>>> vtkSmartPointer does.
>>>>
>>>> Hopefully this makes things a little clearer. At the end of the day all
>>>> vtkObject derived classes (read most of the vtk* classes) are implicitly
>>>> reference counted, the choice of vtkNew/vtkSmartPointer should be made
>>>> depending upon how those instances will be used in your code - both will
>>>> decrement the reference count by one when they go out of scope.
>>>>
>>>> Marcus
>>>>
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: David Thompson <david.thompson at kitware.com>
>>>> To: "Marcus D. Hanwell" <marcus.hanwell at kitware.com>
>>>> Cc: Fcs <ftpronk at engits.com>, VTK Users <vtkusers at vtk.org>
>>>> Bcc:
>>>> Date: Mon, 28 May 2018 10:30:06 -0400
>>>> Subject: Re: [vtkusers] Understanding vtkSmartPointers
>>>> > ...
>>>> > I think I wrote something similar back then. Whenever I see code like
>>>> >
>>>> > vtkSmartPointer<vtkRenderer> renderer =
>>>> vtkSmartPointer<vtkRenderer>::New();
>>>> >
>>>> > I want to replace it with
>>>> >
>>>> > vtkNew<vtkRenderer> renderer;
>>>>
>>>> With c++11, you can also say
>>>>
>>>> auto renderer = vtkSmartPointer<vtkRenderer>::New();
>>>>
>>>> which cleans up the smart-pointer case a little bit.
>>>>
>>>> David
>>>>
>>>>
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: "Marcus D. Hanwell" <marcus.hanwell at kitware.com>
>>>> To: David Thompson <david.thompson at kitware.com>
>>>> Cc: Fcs <ftpronk at engits.com>, VTK Users <vtkusers at vtk.org>
>>>> Bcc:
>>>> Date: Mon, 28 May 2018 10:50:35 -0400
>>>> Subject: Re: [vtkusers] Understanding vtkSmartPointers
>>>> On Mon, May 28, 2018 at 10:30 AM, David Thompson <
>>>> david.thompson at kitware.com> wrote:
>>>>
>>>>> > ...
>>>>> > I think I wrote something similar back then. Whenever I see code like
>>>>> >
>>>>> > vtkSmartPointer<vtkRenderer> renderer =
>>>>> vtkSmartPointer<vtkRenderer>::New();
>>>>> >
>>>>> > I want to replace it with
>>>>> >
>>>>> > vtkNew<vtkRenderer> renderer;
>>>>>
>>>>> With c++11, you can also say
>>>>>
>>>>> auto renderer = vtkSmartPointer<vtkRenderer>::New();
>>>>>
>>>>> which cleans up the smart-pointer case a little bit.
>>>>>
>>>>> For sure, although in the case of class member variables it doesn't
>>>> help, and I would argue vtkNew is cleaner (and vtkNew still uses far fewer
>>>> characters, you got to preserve the finite resources on disk :P ).
>>>>
>>>>
>>>>
>>>> ---------- Forwarded message ----------
>>>> From: Fcs <ftpronk at engits.com>
>>>> To: vtkusers at vtk.org
>>>> Cc:
>>>> Bcc:
>>>> Date: Mon, 28 May 2018 08:45:51 -0700 (MST)
>>>> Subject: Re: [vtkusers] Understanding vtkSmartPointers
>>>> Dear Mathieu, Marcus and David, thank you for your replies and tips,
>>>> with a
>>>> special thank to Marcus for his extensive explanations which really
>>>> clarified a few of the subtleties of the VTK pointers.
>>>>
>>>> Marcus, I had few extra questions linked to your reply.
>>>>
>>>>
>>>> > I In my opinion you should aim to never call Delete, but to have a
>>>> smart
>>>> > pointer contain the things needed.
>>>>
>>>> Is there any danger in calling Delete()? The case I had in mind was to
>>>> perhaps free the memory occupied by a big structured/unstructured grid
>>>> object which would need to live until a sub-grid is extracted from it.
>>>>
>>>>
>>>> > I think all pipeline API will increase
>>>> > the reference count, and so you only usually need to keep a reference
>>>> to
>>>> > the pipeline objects you are going to keep around/use. The debug leaks
>>>> > code
>>>> > will help you verify you got it right.
>>>>
>>>> How good is the guarantee that this will work? "I think" and "usually"
>>>> seem
>>>> to imply that my mileage might vary on this one.. :-) Does it mean that
>>>> this should work in general, but that perhaps some exotic or slightly
>>>> buggy
>>>> newer features might not behave correctly? The use case I'm trying to
>>>> implement has a variable number of pre-definied filters which I'm
>>>> chaining
>>>> together. If I test all the possible combinations, and they work, do I
>>>> have
>>>> the guarantee they will always work?
>>>>
>>>>
>>>> > I would add that we have found in bigger applications that a passing
>>>> debug
>>>> > leaks is not always enough, ensuring objects are deleted when they are
>>>> > done with is more difficult but necessary, especially in graphical
>>>> > applications that might run for some time.
>>>>
>>>> Does this not imply that every vtkObject created should be stored and
>>>> deleted manually afterwards? Or are there other ways to detect living
>>>> vtkObjects when you don't have a direct member variable pointing to it?
>>>> (say, like the vtkPlane created in applyFilters() in my example code..)
>>>>
>>>>
>>>> > It does the exact same thing with no repetition, and is clearer. The
>>>> > examples require backwards compatibility with older VTK, and I don't
>>>> think
>>>> > Bill liked calling .GetPointer()/.Get() on the vtkNew object. You no
>>>> > longer have to do that, but it is a more recent addition to the
>>>> vtkNew API
>>>> > - it will implicitly return the pointer to the contained object as
>>>> > vtkSmartPointer does.
>>>>
>>>> Good to know! Starting from which version is the call to
>>>> .GetPointer()/.Get() no longer needed? We are developing in vtk 6 at the
>>>> moment, but we should update to a new version at some point in the near
>>>> future.
>>>>
>>>> Kind regards,
>>>>
>>>> Francois.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html
>>>>
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at
>>>> http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Please keep messages on-topic and check the VTK FAQ at:
>>>> http://www.vtk.org/Wiki/VTK_FAQ
>>>>
>>>> Search the list archives at: http://markmail.org/search/?q=vtkusers
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> https://vtk.org/mailman/listinfo/vtkusers
>>>>
>>>
>>>
>>> --
>>> ___________________________________________
>>> Andrew J. P. Maclean
>>>
>>> ___________________________________________
>>>
>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Please keep messages on-topic and check the VTK FAQ at:
>> http://www.vtk.org/Wiki/VTK_FAQ
>>
>> Search the list archives at: http://markmail.org/search/?q=vtkusers
>>
>> Follow this link to subscribe/unsubscribe:
>> https://public.kitware.com/mailman/listinfo/vtkusers
>>
>
--
___________________________________________
Andrew J. P. Maclean
___________________________________________
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20180531/9e54036f/attachment.html>
More information about the vtkusers
mailing list