Memory leaks in vtkRenderWindow with parentId

I created a simple application to better explain the issue I’m encountering in my main project. In my main application, I use MFC and set the CChildFrame as the parent window for VTK. Since calling iren->Start() causes the VTK window to open and block until the VTK event loop exits (which prevents my MFC app from starting properly), I use iren->Initialize() instead of Start().

However, when I close the MFC application, I encounter memory leaks that don’t occur when I use the Start() method. I’ve tried adding cleanup code in both the OnDestroy function and the destructor of CChildFrame, but this hasn’t resolved the leaks.

Is there a better approach to avoid these memory leaks when using Initialize function?

int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CMDIChildWndEx::OnCreate(lpCreateStruct) == -1)
		return -1;
	vtkNew<vtkNamedColors> colors;

	std::array<std::array<double, 3>, 8> pts = { { { { 0, 0, 0 } },
	{ { 1, 0, 0 } },
	{ { 1, 1, 0 } },
	{ { 0, 1, 0 } },
	{ { 0, 0, 1 } },
	{ { 1, 0, 1 } },
	{ { 1, 1, 1 } },
	{ { 0, 1, 1 } } } };
	
	std::array<std::array<vtkIdType, 4>, 6> ordering = { { { { 0, 3, 2, 1 } },
	{ { 4, 5, 6, 7 } },
	{ { 0, 1, 5, 4 } },
	{ { 1, 2, 6, 5 } },
	{ { 2, 3, 7, 6 } },
	{ { 3, 0, 4, 7 } } } };

	
	vtkNew<vtkPolyData> cube;
	vtkNew<vtkPoints> points;
	vtkNew<vtkCellArray> polys;
	vtkNew<vtkFloatArray> scalars;

	
	for (auto i = 0ul; i < pts.size(); ++i)
	{
		points->InsertPoint(i, pts[i].data());
		scalars->InsertTuple1(i, i);
	}
	for (auto&& i : ordering)
	{
		polys->InsertNextCell(vtkIdType(i.size()), i.data());
	}

	cube->SetPoints(points);
	cube->SetPolys(polys);
	cube->GetPointData()->SetScalars(scalars);

	vtkNew<vtkPolyDataMapper> cubeMapper;
	cubeMapper->SetInputData(cube);
	cubeMapper->SetScalarRange(cube->GetScalarRange());
	vtkNew<vtkActor> cubeActor;
	cubeActor->SetMapper(cubeMapper);


	renderer = vtkSmartPointer<vtkRenderer>::New();
	renWin = vtkSmartPointer<vtkRenderWindow>::New();
	renWin->AddRenderer(renderer);
	renWin->SetWindowName("Cube");

	iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	iren->SetRenderWindow(renWin);

	renderer->AddActor(cubeActor);
	
	renderer->ResetCamera();
	renderer->SetBackground(colors->GetColor3d("Cornsilk").GetData());

	renWin->SetSize(400, 400);
	renWin->SetParentId(this->GetSafeHwnd());

	iren->Initialize();
	
	return 0;
}
CChildFrame::~CChildFrame()
{
	if (iren)
	{
		iren->TerminateApp();
		iren->SetRenderWindow(nullptr); 
		iren = nullptr;
	}

	if (renWin)
	{
		renWin->RemoveRenderer(this->renderer);
		renWin = nullptr;
	}

	if (renderer)
	{
		renderer = nullptr;
	}
}

Detected memory leaks!
Dumping objects →
{50330} normal block at 0x000002D8852BDD50, 32 bytes long.
Data: 4F 70 65 6E 47 4C 20 44 65 76 20 52 65 6E 64 65
{50277} normal block at 0x000002D8852BDA50, 32 bytes long.
Data: 4F 70 65 6E 47 4C 20 44 65 76 20 52 65 6E 64 65
{50204} normal block at 0x000002D8852BE530, 32 bytes long.
Data: 4F 70 65 6E 47 4C 20 44 65 76 20 52 65 6E 64 65
{50132} normal block at 0x000002D8852BDCF0, 32 bytes long.
Data: 4F 70 65 6E 47 4C 20 44 65 76 20 52 65 6E 64 65
{49858} normal block at 0x000002D8852BDC90, 32 bytes long.
Data: 4F 70 65 6E 47 4C 20 44 65 76 20 52 65 6E 64 65
{49786} normal block at 0x000002D8852BE470, 32 bytes long.

Data: 4F 76 65 72 72 69 64 65 20 66 6F 72 20 76 74 6B
{2251} normal block at 0x000002D8F6BF5E10, 29 bytes long.
Data: 76 74 6B 49 6E 74 65 72 61 63 74 6F 72 53 74 79
{2250} normal block at 0x000002D8F6BAD570, 400 bytes long.
Data: < ^ > 10 5E BF F6 D8 02 00 00 CD CD CD CD CD CD CD CD
{2249} normal block at 0x000002D8F6BB0110, 1600 bytes long.
Data: < pR > D0 D8 C0 F6 D8 02 00 00 70 52 BF F6 D8 02 00 00
{2248} normal block at 0x000002D8F6BC4870, 104 bytes long.
Data: <8DOM > 38 44 4F 4D FD 7F 00 00 CD CD CD CD 01 00 00 00

@sankhesh

@gistam - Instead of calling iren->Initialize() in OnCreate(), please instantiate a CView and call vtkMFCWindow::DrawDC in the CView::OnDraw method so that the framework manages the event loop.