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:
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.