Segmentation fault while writing vtkImageData

I have a function to generate a vtkImageData():

vtkImageData* generateImage(int size[3])
{
  vtkSmartPointer<vtkImageData> img = vtkSmartPointer<vtkImageData>::New();
  img->SetDimensions(size);
  img->AllocateScalars(VTK_SHORT, 1);
  // ......
  return img;
}

Then in the main function I tried to write the image using vtkNIFTIImageWriter:

int main()
{
  // ...
  vtkNew<vtkNIFTIImageWriter> writer;
  writer->SetFileName(fileName);
  writer->SetInputData(generateImage(size));
  writer->Update();
}

Then the program output a segmentation fault at the line:writer->SetInputData().
How to fix this error ? Why does it happen?

The bug may happen for generateImage(size).

You can rearrange the code as:

auto img = generateImage(size);
writer->SetInputData(img);

On the other hand, you need to use writer->Write() to save image rather than writer->Update().

The crash occurs because the smart pointer is deleted at the at the end of generateImage(). So the pointer received by SetInputData() is invalid, because it points to a deleted object. That is why the code crashes.

To fix this, you must return the smart pointer so that the object is not deleted:

vtkSmartPointer<vtkImageData> generateImage(int size[3])

And then you must catch the smart pointer before calling SetInputData():

auto img = generateImage(size);
writer->SetInputData(img);

It is necessary to catch the smart pointer in a variable so that it will be deleted at the end of main(). If you pass the smart pointer directly to SetInputData() without catching it in a variable, then there will be a memory leak.

The things to watch out for are when a vtkSmartPointer is returned as a regular pointer, or when a vtkSmartPointer is passed to a method as a regular pointer.

4 Likes