[vtkusers] Understanding vtkSmartPointers

Elvis Stansvik elvis.stansvik at orexplore.com
Wed May 30 11:42:50 EDT 2018


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://public.kitware.com/pipermail/vtkusers/attachments/20180530/7a706a7e/attachment.html>


More information about the vtkusers mailing list