VTK/Tutorials/SmartPointers: Difference between revisions

From KitwarePublic
< VTK‎ | Tutorials
Jump to navigationJump to search
No edit summary
No edit summary
Line 34: Line 34:
In the first case, when the reader object goes out of scope, the data is deleted. In the second case, by using a smart pointer we have incremented the data's reference count by 1, so the data will not be deleted until the reader AND the polydata object go out of scope.
In the first case, when the reader object goes out of scope, the data is deleted. In the second case, by using a smart pointer we have incremented the data's reference count by 1, so the data will not be deleted until the reader AND the polydata object go out of scope.


==Pitfalls==
* If you create an object and then change where it is pointing, the reference count will be incorrect. e.g.
<source lang="cpp">
vtkSmartPointer<vtkPolyData> Polydata = vtkSmartPointer<vtkPolyData>::New();
Polydata = Reader->GetOutput();
</source>
In this case, memory is allocated for Polydata, but then we change Polydata to point to the output of Reader rather than the memory we just allocated. Instead, we should have done simply:
<source lang="cpp">
vtkPolyData* Polydata = Reader->GetOutput();
</source>
It was not necessary to use a smart pointer because we did not actually create any new objects.
==Example==
Here is an example of equivalent operations with and without smart pointers:
Here is an example of equivalent operations with and without smart pointers:
== SmartPointers.cpp ==
 
===SmartPointers.cpp===
<source lang="cpp">
<source lang="cpp">
#include <vtkFloatArray.h>
#include <vtkFloatArray.h>
Line 66: Line 81:
</source>
</source>


== CMakeLists.txt ==
===CMakeLists.txt===
<source lang="text">
<source lang="text">
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 2.6)

Revision as of 13:36, 31 October 2009

One way to create a VTK object is <source lang="cpp"> vtkObject* MyObject = vtkObject::New(); </source>

This method, however, can (and likely will) lead to memory management issues at some point or another. You must manually delete the object <source lang="cpp"> MyObject->Delete(); </source>

or you will have a memory leak. VTK's solution to this ever-annoying problem is the smart pointer. To use it, you must

<source lang="cpp">

  1. include "vtkSmartPointer.h"

</source>

Then you can create an object as follows: <source lang="cpp"> vtkSmartPointer<vtkObject> MyObject = vtkSmartPointer<vtkObject>::New(); </source>

The idea behind smart pointers is reference counting. If the object goes out of scope and it is not being used anywhere else, it will be deleted automatically. Pretty 'smart', eh?!

When not allocating memory for an object, you can still use smart pointers. Take this simple example: <source lang="cpp"> vtkSmartPointer<vtkXMLPolyDataReader> Reader = vtkSmartPointer<vtkXMLPolyDataReader>::New(); vtkPolyData* pd = Reader->GetOutput(); </source> vs <source lang="cpp"> vtkSmartPointer<vtkPolyData> pd = Reader->GetOutput(); </source>

In the first case, when the reader object goes out of scope, the data is deleted. In the second case, by using a smart pointer we have incremented the data's reference count by 1, so the data will not be deleted until the reader AND the polydata object go out of scope.

Pitfalls

  • If you create an object and then change where it is pointing, the reference count will be incorrect. e.g.

<source lang="cpp"> vtkSmartPointer<vtkPolyData> Polydata = vtkSmartPointer<vtkPolyData>::New(); Polydata = Reader->GetOutput(); </source> In this case, memory is allocated for Polydata, but then we change Polydata to point to the output of Reader rather than the memory we just allocated. Instead, we should have done simply: <source lang="cpp"> vtkPolyData* Polydata = Reader->GetOutput(); </source>

It was not necessary to use a smart pointer because we did not actually create any new objects.

Example

Here is an example of equivalent operations with and without smart pointers:

SmartPointers.cpp

<source lang="cpp">

  1. include <vtkFloatArray.h>
  2. include <vtkSmartPointer.h>
  1. include <iostream>

void WithSmartPointers(); void WithoutSmartPointers();

int main(int argc, char *argv[]) {

 WithSmartPointers();
 WithoutSmartPointers();

return 0; }

void WithSmartPointers() {

 vtkSmartPointer<vtkFloatArray> Distances = vtkSmartPointer<vtkFloatArray>::New();

}

void WithoutSmartPointers() {

 vtkFloatArray* Distances = vtkFloatArray::New();
 Distances->Delete();

}

</source>

CMakeLists.txt

<source lang="text"> cmake_minimum_required(VERSION 2.6)

PROJECT(SmartPointers)

FIND_PACKAGE(VTK REQUIRED) INCLUDE(${VTK_USE_FILE})

ADD_EXECUTABLE(SmartPointers SmartPointers.cpp)

TARGET_LINK_LIBRARIES(SmartPointers vtkHybrid)

</source>